类型转换关键字:is
、as
、as?
、as!
类型转换可以判断实例的类型,也可以用于检测实例类型是否属于其父类或者子类的实例。类型转换没有真的改变实例或它的值,根本的实例保持不变;只是简单地把它作为它被转换成的类型来使用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| class ClassA { var name:String init(name:String) { self.name = name } }
class ClassB: ClassA { var describe:String init(name: String, describe:String) { self.describe = describe super.init(name: name) } }
class ClassC: ClassA { var type:String init(name:String, type:String) { self.type = type super.init(name: name) } }
let arr: [ClassA] = [ClassB.init(name: "B0", describe: "B0 describe"), ClassC.init(name: "C0", type: "C0 type"), ClassB.init(name: "B1", describe: "B1 describe"), ClassC.init(name: "C1", type: "C1 type"), ClassC.init(name: "C2", type: "C2 type")]
|
检查一个实例是否属于某类型:
1 2 3 4 5 6 7
| let v = arr[1] if v is ClassB { print("ClassB") }else{ print("other") }
|
表示子类转父类(向上转型):
1 2
| let v0 = arr[0] as ClassA print(v0)
|
当不确定父类转子类(向下转型)可以成功时,用类型转换的条件形式 as?
,返回一个可选值。若下转是不可能的,可选值将是 nil
1 2
| let v1 = arr[0] as? ClassC print(v1)
|
可以确定向下转型一定会成功时,才使用强制形式 as!
,向下转型为一个不正确的类型时,强制形式的类型转换会触发一个运行时错误
1 2
| let v2 = arr[0] as! ClassB print(v2)
|
Any 和 AnyObject 的类型转换
- 关键字
Any
:表示任何类型,包括函数类型
- 关键字
AnyObject
:表示任何类类型的实例
1 2 3 4 5 6 7 8
| 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({ (name: String) -> String in "Hello, \(name)" })
|
如果确实想使用 Any
类型来承载可选值,可以使用 as
操作符显式转换为 Any
1 2 3 4
| var things = [Any]() let value:Int? = 3 things.append(value) things.append(value as Any)
|