类型转换的作用
类型转换可以判断实例的类型,也可以将该实例在其所在的类层次中视为其父类或子类的实例。
Swift 中类型转换的实现为 is和 as操作符。这两个操作符使用了一种简单传神的方式来检查一个值的类型或将某个值转换为另一种类型。
你还可以使用类型转换来检查类型是否遵循某个协议。
类型检查
使用类型检查操作符 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(“Media library contains \(movieCount) movies and \(songCount) songs”)
*// Prints “Media library contains 2 movies and 3 songs”*
向下类型转换
类型转换操作符 as? 或 as!将实例向下类型转换至其子类类型
由于向下类型转换能失败,类型转换操作符就有了两个不同形式。条件形式, 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)’, 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*
举个例子
if let movie = item as? Movie
这个写法可以读作:尝试以 Movie 类型访问 item 。如果成功,设置一个新的临时常量 movie 储存返回的可选 Movie 类型 。
类型转换实际上不会改变实例及修改其值。
Any 和 AnyObject 的类型转换
Swift为不确定的类型提供了两种特殊的类型别名:
AnyObject可以表示任何类类型的实例。Any可以表示任何类型,包括函数类型。
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)” })
你可以在 switch 结构的 case 中使用 is 和 as 操作符找出已知 Any或 AnyObject 类型的常量或变量的具体类型。
for thing in things {
switch thing {
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”)
default:
print(“something else”)
}
}
optional类型转换为Any来避免警告
如果你给显式声明的Any类型使用可选项,Swift 就会发出警告 意思是本来应该传入一个Any类型的实参,但你传了一个optional类型的实参,就会报warning。
如果你真心需要在Any值中使用optional类型,可以通过as运算符来显式地将optional类型转换为Any类型来消除警告。
let optionalNumber: Int? = 3
things.append(optionalNumber) *// Warning*
things.append(optionalNumber as Any) *// No warning*
Swift学习群
欢迎加入本人的Swift学习微信群,一同互相监督学习,我微信:reese90