# Swift 類型轉換
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)")
```
以上程序執行輸出結果為:
```
實例物理學是: 固體物理
實例方程式: 赫茲
實例物理學是: 流體動力學
實例公式是: 千兆赫
```
## 檢查類型
類型檢查使用 **is** 關鍵字。
操作符 **is** 來檢查一個實例是否屬于特定子類型。若實例屬于那個子類型,類型檢查操作符返回 true,否則返回 false。
```
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 個主題
```
## 向下轉型
向下轉型,用類型轉換操作符(as? 或 as!)
當你不確定向下轉型可以成功時,用類型轉換的條件形式(as?)。條件形式的類型轉換總是返回一個可選值(optional value),并且若下轉是不可能的,可選值將是 nil。
只有你可以確定向下轉型一定會成功時,才使用強制形式(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)")
}
}
```
以上程序執行輸出結果為:
```
實例物理學是: 固體物理
實例方程式: 赫茲
實例物理學是: 流體動力學
實例公式是: 千兆赫
化學主題是: '固體物理', 赫茲
數學主題是: '流體動力學', 千兆赫
化學主題是: '熱物理學', 分貝
數學主題是: '天體物理學', 兆赫
數學主題是: '微分方程', 余弦級數
```
## Any和AnyObject的類型轉換
Swift為不確定類型提供了兩種特殊類型別名:
* `AnyObject`可以代表任何class類型的實例。
* `Any`可以表示任何類型,包括方法類型(function types)。
> 注意:
> 只有當你明確的需要它的行為和功能時才使用`Any`和`AnyObject`。在你的代碼里使用你期望的明確的類型總是更好的。
### 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?)來檢查和轉換到一個明確的類型。
- Swift 簡介
- Swift 環境搭建
- Swift 基本語法
- Swift 數據類型
- Swift 變量
- Swift 可選(Optionals)類型
- Swift 常量
- Swift 字面量
- Swift 運算符
- Swift 條件語句
- Swift if 語句
- Swift if...else 語句
- Swift if...else if...else 語句
- Swift 嵌套 if 語句
- Swift switch 語句
- Swift 循環
- Swift for-in 循環
- Swift for 循環
- Swift While 循環
- Swift repeat...while 循環
- Swift Continue 語句
- Swift Break 語句
- Swift Fallthrough 語句
- Swift 字符串
- Swift 字符(Character)
- Swift 數組
- Swift 字典
- Swift 函數
- Swift 閉包
- Swift 枚舉
- Swift 結構體
- Swift 類
- Swift 屬性
- Swift 方法
- Swift 下標腳本
- Swift 繼承
- Swift 構造過程
- Swift 析構過程
- Swift 可選鏈
- Swift 自動引用計數(ARC)
- Swift 類型轉換
- Swift 擴展
- Swift 協議
- Swift 泛型
- Swift 訪問控制