Swift-类型转换

Swift语言类型转换可以判断实例的类型,也可以用于检测实例类型是都属于其父类或者子类的实例。Swift中类型转换使用is和as操作符实现,is用于检测值得类型,as用于转换类型。类型转换也可以用来检查一个类是否实现了某个协议。

检查类型

类型转换用于检测实例类型是否属于特定的实例类型。类型价差使用is关键字,来检查一个实例是否属于特定子类型,若实例属于那个子类型,返回true,否则返回false

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
30
31
32
33
34
35
36
37
38
39
40
41
42
class Subjects{
var physics:String
init(physics:String) {
self.physics = physics
}
}

class Chemistry: Subjects {
var equations:String
init(physics:String, equations:String) {
self.equations = equations
super.init(physics: physics)
}
}

class Maths: Subjects {
var formulae:String
init(physics:String, formulae:String) {
self.formulae = formulae
super.init(physics: physics)
}
}

let array = [Chemistry(physics: "固体物理", equations: "赫兹"),
Maths(physics: "流体动力学", formulae: "千兆赫"),
Chemistry(physics: "热学物理", equations: "分贝"),
Maths(physics: "天体梯物理学", formulae: "赫兹"),
Maths(physics: "微分方程", formulae: "余弦级数")]

var chemCount = 0
var mathCount = 0
for item in array {
// 如果是一个Chemistry类型的实例,返回true,否则返回false
if item is Chemistry{
chemCount += 1
} else if item is Maths{
mathCount += 1
}
}

print("Chemistry课题数目:\(chemCount), Maths课题数目:\(mathCount)")
// Chemistry课题数目:2, Maths课题数目:3

向下转型

向下转型:使用类型转换操作符(as? 或 as!)

  1. 不确定向下转型是否成功,使用as?,返回一个可选值。
  2. 确定向下转型成功,使用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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
class Subjects{
var physics:String
init(physics:String) {
self.physics = physics
}
}

class Chemistry: Subjects {
var equations:String
init(physics:String, equations:String) {
self.equations = equations
super.init(physics: physics)
}
}

class Maths: Subjects {
var formulae:String
init(physics:String, formulae:String) {
self.formulae = formulae
super.init(physics: physics)
}
}

let array = [Chemistry(physics: "固体物理", equations: "赫兹"),
Maths(physics: "流体动力学", formulae: "千兆赫"),
Chemistry(physics: "热学物理", equations: "分贝"),
Maths(physics: "天体梯物理学", formulae: "赫兹"),
Maths(physics: "微分方程", formulae: "余弦级数")]

for item in array{
if let typeChemistry = item as? Chemistry{
print("化学主题是:\(typeChemistry.physics), \(typeChemistry.equations)")
} else if let typeMath = item as? Maths{
print("物理主题是:\(typeMath.physics), \(typeMath.formulae)")
}
}
//化学主题是:固体物理, 赫兹
//物理主题是:流体动力学, 千兆赫
//化学主题是:热学物理, 分贝
//物理主题是:天体梯物理学, 赫兹
//物理主题是:微分方程, 余弦级数


var chemistry:Subjects = Chemistry(physics: "固体物理", equations: "赫兹")
// 使用as!进行转换,确保是正确的类型,否则发生运行时错误
let typeChemistry = chemistry as! Chemistry
print("化学主题是:\(typeChemistry.physics), \(typeChemistry.equations)")
// 化学主题是:固体物理, 赫兹

Any和AnyObject的类型转换

Swift为不确定类型提供了两种特殊类型别名:

  • AnyObject可以代表任何class类型的实例
  • Any可以表示任何类型,包括方法类型(function types)

注意:只有当你明确的需要它的行为和功能是才使用Any和AnyObject

Any实例
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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
class Subjects{
var physics:String
init(physics:String) {
self.physics = physics
}
}

class Chemistry: Subjects {
var equations:String
init(physics:String, equations:String) {
self.equations = equations
super.init(physics: physics)
}
}

// 存储Any类型的数组
var anyArray = [Any]()

anyArray.append(12)
anyArray.append(0.37)
anyArray.append("Any string")
anyArray.append(true)
anyArray.append(Chemistry(physics: "固体物理", equations: "赫兹"))

for item in anyArray{
switch item {
case let someInt as Int:
print("Int 类型:\(someInt)")
case let someDouble as Double where someDouble > 0:
print("Double类型:\(someDouble)")
case let someString as String:
print("String类型:\(someString)")
case let someBool as Bool:
print("Bool类型:\(someBool)")
case let someChemistry as Chemistry:
print("化学主题是:\(someChemistry.physics), \(someChemistry.equations)")
default:
print("未知类型")
}
}
//Int 类型:12
//Double类型:0.37
//String类型:Any string
//Bool类型:true
//化学主题是:固体物理, 赫兹

在switch语句的case中使用强制形式的类型转换操作符(as,而不是as?)来检查和转换一个明确的类型

AnyObject实例
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
30
31
32
33
34
35
36
37
38
39
40
41
class Subjects{
var physics:String
init(physics:String) {
self.physics = physics
}
}

class Chemistry: Subjects {
var equations:String
init(physics:String, equations:String) {
self.equations = equations
super.init(physics: physics)
}
}

class Maths: Subjects {
var formulae:String
init(physics:String, formulae:String) {
self.formulae = formulae
super.init(physics: physics)
}
}

let anyObjectArray:[AnyObject] = [Chemistry(physics: "固体物理", equations: "赫兹"),
Maths(physics: "流体动力学", formulae: "千兆赫"),
Chemistry(physics: "热学物理", equations: "分贝"),
Maths(physics: "天体梯物理学", formulae: "赫兹"),
Maths(physics: "微分方程", formulae: "余弦级数")]

for item in anyObjectArray{
if let typeChemistry = item as? Chemistry{
print("化学主题是:\(typeChemistry.physics), \(typeChemistry.equations)")
} else if let typeMath = item as? Maths{
print("物理主题是:\(typeMath.physics), \(typeMath.formulae)")
}
}
//化学主题是:固体物理, 赫兹
//物理主题是:流体动力学, 千兆赫
//化学主题是:热学物理, 分贝
//物理主题是:天体梯物理学, 赫兹
//物理主题是:微分方程, 余弦级数

强制类型转换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
var intValue:Int = 10
var doubleValue:Double
// 注意:Double()并不会修改intValue的值, 而是通过intValue的值生成一个临时的值赋值给doubleValue
doubleValue = Double(intValue)

print(intValue) // 10
print(doubleValue) // 10.0

var doubleValue1:Double = 1.99
var intValue1:Int
intValue1 = Int(doubleValue1)
print(intValue1) // 1
print(doubleValue1) // 1.99

var stringValue:String = "555"
var stringValue1:String = "55.5"
var intValue2:Int
var doubleValue2:Double
intValue2 = Int(stringValue)!
doubleValue2 = Double(stringValue1)!
print(intValue2) // 555
print(stringValue) // 555
print(doubleValue2) // 55.5

参考: