向下转型(Downcasting)
某类型的一个常量或变量可能在幕后实际上属于一个子类。你可以相信,上面就是这种情况。你可以尝试向下转到它的子类型,用类型转换操作符(as
)
因为向下转型可能会失败,类型转型操作符带有两种不同形式。可选形式( optional form) as?
返回一个你试图下转成的类型的可选值(optional value)。强制形式 as
把试图向下转型和强制解包(force-unwraps)结果作为一个混合动作。
当你不确定向下转型可以成功时,用类型转换的可选形式(as?
)。可选形式的类型转换总是返回一个可选值(optional value),并且若下转是不可能的,可选值将是 nil
。这使你能够检查向下转型是否成功。
只有你可以确定向下转型一定会成功时,才使用强制形式。当你试图向下转型为一个不正确的类型时,强制形式的类型转换会触发一个运行时错误。
下面的例子,迭代了library
里的每一个 MediaItem
,并打印出适当的描述。要这样做,item
需要真正作为Movie
或 Song
的类型来使用。不仅仅是作为 MediaItem
。为了能够使用Movie
或 Song
的director
或 artist
属性,这是必要的。
在这个示例中,数组中的每一个item
可能是 Movie
或 Song
。 事前你不知道每个item
的真实类型,所以这里使用可选形式的类型转换 (as?
)去检查循环里的每次下转。
for item in library {
if let movie = item as? Movie {
println("Movie: '\(movie.name)', dir. \(movie.director)")
} else if let song = item as? Song {
println("Song: '\(song.name)', by \(song.artist)")
}
}
// Movie: 'Casablanca', dir. Michael Curtiz
// Song: 'Blue Suede Shoes', by Elvis Presley
// Movie: 'Citizen Kane', dir. Orson Welles
// Song: 'The One And Only', by Chesney Hawkes
// Song: 'Never Gonna Give You Up', by Rick Astley
示例首先试图将 item
下转为 Movie
。因为 item
是一个 MediaItem
类型的实例,它可能是一个Movie
;同样,它可能是一个 Song
,或者仅仅是基类 MediaItem
。因为不确定,as?
形式在试图下转时将返还一个可选值。 item as Movie
的返回值是Movie?
类型或 “optional Movie
”。
当向下转型为 Movie
应用在两个 Song
实例时将会失败。为了处理这种情况,上面的例子使用了可选绑定(optional binding)来检查可选 Movie
真的包含一个值(这个是为了判断下转是否成功。)可选绑定是这样写的“if let movie = item as? Movie
”,可以这样解读:
“尝试将 item
转为 Movie
类型。若成功,设置一个新的临时常量 movie
来存储返回的可选Movie
”
若向下转型成功,然后movie
的属性将用于打印一个Movie
实例的描述,包括它的导演的名字director
。当Song
被找到时,一个相近的原理被用来检测 Song
实例和打印它的描述。
注意:
转换没有真的改变实例或它的值。潜在的根本的实例保持不变;只是简单地把它作为它被转换成的类来使用。
易百教程移动端:请扫描本页面底部(右侧)二维码并关注微信公众号,回复:"教程" 选择相关教程阅读或直接访问:http://m.yiibai.com 。
加QQ群啦,易百教程官方技术学习群
注意:建议每个人选自己的技术方向加群,同一个QQ最多限加 3 个群。
- Java技术群: 227270512 (人数:2000,免费:否)
- Go开发者群(新): 851549018 (人数:1000,免费)
- PHP开发者群: 460153241 (人数:2000,免费)
- MySQL/SQL群: 418407075 (人数:2000,免费:否)
- 大数据开发群: 655154550 (人数:2000,免费:否)
- Python技术群: 287904175 (人数:2000,免费:否)
- 人工智能深度学习: 456236082 (人数:2000,免费:否)
- 测试工程师群: 415553199 (人数:2000,免费:否)
- 前端开发者群: 410430016 (人数:2000,免费:否)
- C/C++技术群(新): 629264796 (人数:2000,免费)
- Node.js技术群(新): 621549808 (人数:2000,免费)
- PostgreSQL数据库群: 539504187 (人数:1000,免费)
- Linux运维技术群: 479429477 (人数:2000,免费:否)
- Oracle数据库: 175248146 (人数:2000,免费:否)
- C#/ASP.Net开发者: 579821706 (人数:2000,免费)
- 数据分析师群: 397883996 (人数:2000,免费:否)