19:swift-类型转换
正文
/* 类型转换 1:类型转换 类型转换可以判断实例的类型,也可以将该实例在其所在的类层次中视为其父类或子类的实例。 Swift 中类型转换的实现为 is 和 as 操作符。 这两个操作符使用了一种简单传神的方式来检查一个值的类型或将某个值转换为另一种类型 你还可以使用类型转换来检查类型是否遵循某个协议。 4: Any类型 类、结构体或者枚举; 元类型,比如 Int.self ; 带有任意类型元素的元组; 闭包或者函数类型 AnyObject类型 所有类都隐式遵循AnyObject协议,这也限制了AnyObject是只适用于Class类型的原因。 */ import UIKit class TypeConvert19VC: UIViewController { override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = .white self.title = "19:类型转换" /* 1:创建数组 如果你遍历这个数组的内容,你取出的项目将会是 MediaItem 类型而非 Movie 或 Song 类型。为了使用他们原生的类型,你需要检查他们的类型或将他们向下转换为不同的类型, */ let library = [ Movie(name: "Casablanca", director: "Michael Curtiz"), Song(name: "Blue Suede Shoes", artist: "Elvis Presley"), Movie(name: "Citizen Kane", director: "Orson Welles"), Song(name: "The One And Only", artist: "Chesney Hawkes"), Song(name: "Never Gonna Give You Up", artist: "Rick Astley") ] var movieCount = 0 var songCount = 0 for item in library { if item is Movie { movieCount += 1 } else if item is Song { songCount += 1 } } print("Media library contains \(movieCount) movies and \(songCount) songs") /* 2:向下转换 某个类类型的常量或变量可能实际上在后台引用自一个子类的实例。 当你遇到这种情况时你可以尝试使用类型转换操作符( as? 或 as! )将它向下类型转换至其子类类型。 由于向下类型转换能失败,类型转换操作符就有了两个不同形式。 条件形式, as? ,返回了一个你将要向下类型转换的值的可选项。 强制形式, as! ,则将向下类型转换和强制展开结合为一个步骤。 类型转换实际上不会改变实例及修改其值。实例不会改变;它只是将它当做要转换的类型来访问。 */ for item in library { if let movie = item as? Movie { print("Movie: '\(movie.name)', dir. \(movie.director)") } else if let song = item as? Song { print("Song: '\(song.name)', by \(song.artist)") } } /* 3: Any 和 AnyObject 的类型转换 */ var things = [Any]() things.append(0) things.append(0.0) things.append(42) things.append(3.14159) things.append("hello") things.append((3.0, 5.0)) things.append(Movie(name: "Ghostbusters", director: "Ivan Reitman")) things.append({ (name: String) -> String in "Hello, \(name)" }) for thing in things { switch thing { case 0 as Int: print("zero as an Int") case 0 as Double: print("zero as a Double") case let someInt as Int: print("an integer value of \(someInt)") case let someDouble as Double where someDouble > 0: print("a positive double value of \(someDouble)") case is Double: print("some other double value that I don't want to print") case let someString as String: print("a string value of \"\(someString)\"") case let (x, y) as (Double, Double): print("an (x, y) point at \(x), \(y)") case let movie as Movie: print("a movie called \(movie.name), dir. \(movie.director)") case let stringConverter as (String) -> String: print(stringConverter("Michael")) default: print("something else") } } /* 3: Any类型表示了任意类型的值,包括可选类型。 如果你给显式声明的Any类型使用可选项,Swift 就会发出警告。 如果你真心需要在Any值中使用可选项,如下所示,你可以使用as运算符来显式地转换可选项为Any。 */ let optionalNumber: Int? = 3 things.append(optionalNumber) // Warning things.append(optionalNumber as Any) // No warning } } // 定义媒体项 class MediaItem { var name: String init(name: String) { self.name = name } } // 定义视频 class Movie: MediaItem { var director: String init(name: String, director: String) { self.director = director super.init(name: name) } } // 定义音频 class Song: MediaItem { var artist: String init(name: String, artist: String) { self.artist = artist super.init(name: name) } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!