Swift 语言类型转换可以判断实例的类型。也可以用于检测实例类型是否属于其父类或者子类的实例,或是否实现了某个协议。
Swift 中类型转换使用 is
和 as
操作符实现,is
用于检测值的类型,as
用于转换类型。
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 sa = [
Chemistry(physics: "固体物理", equations: "赫兹"),
Maths(physics: "流体动力学", formulae: "千兆赫")]
let samplechem = Chemistry(physics: "固体物理", equations: "赫兹")
print("实例物理学是: \(samplechem.physics)")
print("实例方程式: \(samplechem.equations)")
let samplemaths = Maths(physics: "流体动力学", formulae: "千兆赫")
print("实例物理学是: \(samplemaths.physics)")
print("实例公式是: \(samplemaths.formulae)")
// 实例物理学是: 固体物理
// 实例方程式: 赫兹
// 实例物理学是: 流体动力学
// 实例公式是: 千兆赫
1. 检查类型
类型检查使用is
关键字,用于检测实例类型是否属于特定的实例类型。
你可以将它用在类和子类的层次结构上,检查特定类实例的类型并且转换这个类实例的类型成为这个层次结构中的其他类型。
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 sa = [
Chemistry(physics: "固体物理", equations: "赫兹"),
Maths(physics: "流体动力学", formulae: "千兆赫"),
Chemistry(physics: "热物理学", equations: "分贝"),
Maths(physics: "天体物理学", formulae: "兆赫"),
Maths(physics: "微分方程", formulae: "余弦级数")]
let samplechem = Chemistry(physics: "固体物理", equations: "赫兹")
print("实例物理学是: \(samplechem.physics)")
print("实例方程式: \(samplechem.equations)")
let samplemaths = Maths(physics: "流体动力学", formulae: "千兆赫")
print("实例物理学是: \(samplemaths.physics)")
print("实例公式是: \(samplemaths.formulae)")
var chemCount = 0
var mathsCount = 0
for item in sa {
// 如果是一个 Chemistry 类型的实例,返回 true,相反返回 false。
if item is Chemistry {
++chemCount
} else if item is Maths {
++mathsCount
}
}
print("化学科目包含 \(chemCount) 个主题,数学包含 \(mathsCount) 个主题")
// 实例物理学是: 固体物理
// 实例方程式: 赫兹
// 实例物理学是: 流体动力学
// 实例公式是: 千兆赫
// 化学科目包含 2 个主题,数学包含 3 个主题
2. 向下转型
向下转型,用类型转换操作符:as
as?
as!
as |
系统中的大多数的CF对象可以使用as 直接转换为Swift类型 |
---|---|
as? |
当你不确定向下转型可以成功时,用类型转换的条件形式as? 。条件形式的类型转换总是返回一个可选值,并且若下转是不可能的,可选值将是 nil 。 |
as! |
只有你可以确定向下转型一定会成功时,才使用强制形式as! 。当你试图向下转型为一个不正确的类型时,强制形式的类型转换会触发一个运行时错误。 |
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 sa = [
Chemistry(physics: "固体物理", equations: "赫兹"),
Maths(physics: "流体动力学", formulae: "千兆赫"),
Chemistry(physics: "热物理学", equations: "分贝"),
Maths(physics: "天体物理学", formulae: "兆赫"),
Maths(physics: "微分方程", formulae: "余弦级数")]
let samplechem = Chemistry(physics: "固体物理", equations: "赫兹")
print("实例物理学是: \(samplechem.physics)")
print("实例方程式: \(samplechem.equations)")
let samplemaths = Maths(physics: "流体动力学", formulae: "千兆赫")
print("实例物理学是: \(samplemaths.physics)")
print("实例公式是: \(samplemaths.formulae)")
var chemCount = 0
var mathsCount = 0
for item in sa {
// 类型转换的条件形式
if let show = item as? Chemistry {
print("化学主题是: '\(show.physics)', \(show.equations)")
// 强制形式
} else if let example = item as? Maths {
print("数学主题是: '\(example.physics)', \(example.formulae)")
}
}
/*
实例物理学是: 固体物理
实例方程式: 赫兹
实例物理学是: 流体动力学
实例公式是: 千兆赫
化学主题是: '固体物理', 赫兹
数学主题是: '流体动力学', 千兆赫
化学主题是: '热物理学', 分贝
数学主题是: '天体物理学', 兆赫
数学主题是: '微分方程', 余弦级数
*/
3. Any和AnyObject的类型转换
OC中的id
类型在Swift中使用AnyObject
,Swift为不确定类型提供了两种特殊类型别名:
-
AnyObject
可以代表任何class
类型的实例。 -
Any
可以表示任何类型,包括基本类型(Int
Double
)、方法类型(function types)、枚举结构体、指针等。
Any 实例
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 sa = [
Chemistry(physics: "固体物理", equations: "赫兹"),
Maths(physics: "流体动力学", formulae: "千兆赫"),
Chemistry(physics: "热物理学", equations: "分贝"),
Maths(physics: "天体物理学", formulae: "兆赫"),
Maths(physics: "微分方程", formulae: "余弦级数")]
let samplechem = Chemistry(physics: "固体物理", equations: "赫兹")
print("实例物理学是: \(samplechem.physics)")
print("实例方程式: \(samplechem.equations)")
let samplemaths = Maths(physics: "流体动力学", formulae: "千兆赫")
print("实例物理学是: \(samplemaths.physics)")
print("实例公式是: \(samplemaths.formulae)")
var chemCount = 0
var mathsCount = 0
for item in sa {
// 类型转换的条件形式
if let show = item as? Chemistry {
print("化学主题是: '\(show.physics)', \(show.equations)")
// 强制形式
} else if let example = item as? Maths {
print("数学主题是: '\(example.physics)', \(example.formulae)")
}
}
// 可以存储Any类型的数组 exampleany
var exampleany = [Any]()
exampleany.append(12)
exampleany.append(3.14159)
exampleany.append("Any 实例")
exampleany.append(Chemistry(physics: "固体物理", equations: "兆赫"))
for item2 in exampleany {
switch item2 {
case let someInt as Int:
print("整型值为 \(someInt)")
case let someDouble as Double where someDouble > 0:
print("Pi 值为 \(someDouble)")
case let someString as String:
print("\(someString)")
case let phy as Chemistry:
print("主题 '\(phy.physics)', \(phy.equations)")
default:
print("None")
}
}
/*
实例物理学是: 固体物理
实例方程式: 赫兹
实例物理学是: 流体动力学
实例公式是: 千兆赫
化学主题是: '固体物理', 赫兹
数学主题是: '流体动力学', 千兆赫
化学主题是: '热物理学', 分贝
数学主题是: '天体物理学', 兆赫
数学主题是: '微分方程', 余弦级数
整型值为 12
Pi 值为 3.14159
Any 实例
主题 '固体物理', 兆赫
*/
AnyObject 实例
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)
}
}
// [AnyObject] 类型的数组
let saprint: [AnyObject] = [
Chemistry(physics: "固体物理", equations: "赫兹"),
Maths(physics: "流体动力学", formulae: "千兆赫"),
Chemistry(physics: "热物理学", equations: "分贝"),
Maths(physics: "天体物理学", formulae: "兆赫"),
Maths(physics: "微分方程", formulae: "余弦级数")]
let samplechem = Chemistry(physics: "固体物理", equations: "赫兹")
print("实例物理学是: \(samplechem.physics)")
print("实例方程式: \(samplechem.equations)")
let samplemaths = Maths(physics: "流体动力学", formulae: "千兆赫")
print("实例物理学是: \(samplemaths.physics)")
print("实例公式是: \(samplemaths.formulae)")
var chemCount = 0
var mathsCount = 0
for item in saprint {
// 类型转换的条件形式
if let show = item as? Chemistry {
print("化学主题是: '\(show.physics)', \(show.equations)")
// 强制形式
} else if let example = item as? Maths {
print("数学主题是: '\(example.physics)', \(example.formulae)")
}
}
var exampleany = [Any]()
exampleany.append(12)
exampleany.append(3.14159)
exampleany.append("Any 实例")
exampleany.append(Chemistry(physics: "固体物理", equations: "兆赫"))
for item2 in exampleany {
switch item2 {
case let someInt as Int:
print("整型值为 \(someInt)")
case let someDouble as Double where someDouble > 0:
print("Pi 值为 \(someDouble)")
case let someString as String:
print("\(someString)")
case let phy as Chemistry:
print("主题 '\(phy.physics)', \(phy.equations)")
default:
print("None")
}
}
/*
实例物理学是: 固体物理
实例方程式: 赫兹
实例物理学是: 流体动力学
实例公式是: 千兆赫
化学主题是: '固体物理', 赫兹
数学主题是: '流体动力学', 千兆赫
化学主题是: '热物理学', 分贝
数学主题是: '天体物理学', 兆赫
数学主题是: '微分方程', 余弦级数
整型值为 12
Pi 值为 3.14159
Any 实例
主题 '固体物理', 兆赫
*/
在一个
switch
语句的case
中使用强制形式的类型转换操作符as
(而不是as?
)来检查和转换到一个明确的类型(这是模式匹配,将在其他章节讲解,这里记住如何使用即可)。