//类型转换
//“类型转换 可以判断实例的类型,也可以将实例看做是其父类或者子类的实例。”
//“类型转换在 Swift 中使用 is 和 as 操作符实现。这两个操作符提供了一种简单达意的方式去检查值的类型或者转换它的类型。”
//1.定义一个类层次作为例子。
//“你可以将类型转换用在类和子类的层次结构上,检查特定类实例的类型并且转换这个类实例的类型成为这个层次结构中的其他类型”
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)
}
}
let library = [
Movie("casablanca","michelecurtiz"),
Song("blue suede shoes","jac"),
Movie("cicizen","orsonWelles"),
Song("the One","ceheneyhawkes"),
]
//“ 数组 library 的类型被推断为 [MediaItem]”
//“在幕后 library 里存储的媒体项依然是 Movie 和 Song 类型的。但是,若你迭代它,依次取出的实例会是 MediaItem 类型的,而不是 Movie 和 Song 类型。为了让它们作为原本的类型工作,你需要检查它们的类型或者向下转换它们到其它类型,就像下面描述的一样。”
//2. 检查类型
//“用类型检查操作符(is)来检查一个实例是否属于特定子类型。若实例属于那个子类型,类型检查操作符返回 true,否则返回 false。”
var movieCount = 0
var songCount = 0
for item in library {
if item is Movie {
movieCount += 1
}else if item is Song {
songCount += 1
}
}
print("movie count is \(movieCount),song count is \(songCount)")
//3. 向下转型
//“某类型的一个常量或变量可能在幕后实际上属于一个子类。当确定是这种情况时,你可以尝试向下转到它的子类型,用类型转换操作符(as? 或 as!)”
//“因为向下转型可能会失败,类型转型操作符带有两种不同形式。条件形式as? 返回一个你试图向下转成的类型的可选值。强制形式 as! 把试图向下转型和强制解包(转换结果结合为一个操作。当你不确定向下转型可以成功时,用类型转换的条件形式(as?)。条件形式的类型转换总是返回一个可选值,并且若下转是不可能的,可选值将是 nil。这使你能够检查向下转型是否成功。”
//“只有你可以确定向下转型一定会成功时,才使用强制形式(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),artist \(song.artist)")
}
}
//“注意 转换没有真的改变实例或它的值。根本的实例保持不变;只是简单地把它作为它被转换成的类型来使用。”
//4.any 和anyObject的类型转换
//“Swift 为不确定类型提供了两种特殊的类型别名:
/*
Any 可以表示任何类型,包括函数类型。
AnyObject 可以表示任何类类型的实例。”
*/
var things = [Any]()
things.append(0)
things.append(3.14)
things.append("hello")
things.append(Movie("taitannice","kameilong"))
//“你可以在 switch 表达式的 case 中使用 is 和 as 操作符来找出只知道是 Any 或 AnyObject 类型的常量或变量的具体类型”
for thing in things {
switch thing {
case 0 as Int:
print("zero as an int")
case let someDouble as Double where someDouble > 0:
print("a positive double value of \(someDouble)")
case is Double:
print("some other double that i don't want to print")
case let someString as String:
print("s string \(someString)")
case let movie as Movie:
print("a movie called \(movie.name)")
default :
print(" not the above")
}
}
//“注意 Any类型可以表示所有类型的值,包括可选类型。Swift 会在你用Any类型来表示一个可选值的时候,给你一个警告。如果你确实想使用Any类型来承载可选值,你可以使用as操作符显示转换为Any,”
let optionalNumber:Int? = 3
things.append(optionalNumber)//警告
things.append(optionalNumber as Any) //没有警告
网友评论