发布于 2015-06-14 01:45:39 | 310 次阅读 | 评论: 0 | 来源: 网络整理
某类型的一个常量或变量可能在幕后实际上属于一个子类。你可以相信,上面就是这种情况。你可以尝试向下转到它的子类型,用类型转换操作符(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
实例和打印它的描述。
注意:
转换没有真的改变实例或它的值。潜在的根本的实例保持不变;只是简单地把它作为它被转换成的类来使用。