Swift 類型轉(zhuǎn)換
Swift 語言類型轉(zhuǎn)換可以判斷實例的類型。也可以用于檢測實例類型是否屬于其父類或者子類的實例。
Swift 中類型轉(zhuǎn)換使用 is 和 as 操作符實現(xiàn),is 用于檢測值的類型,as 用于轉(zhuǎn)換類型。
類型轉(zhuǎn)換也可以用來檢查一個類是否實現(xiàn)了某個協(xié)議。
定義一個類層次
類型轉(zhuǎn)換用于檢測實例類型是否屬于特定的實例類型。
你可以將它用在類和子類的層次結(jié)構(gòu)上,檢查特定類實例的類型并且轉(zhuǎn)換這個類實例的類型成為這個層次結(jié)構(gòu)中的其他類型。
實例如下:
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)")
以上程序執(zhí)行輸出結(jié)果為:
實例物理學是: 固體物理 實例方程式: 赫茲 實例物理學是: 流體動力學 實例公式是: 千兆赫
檢查類型
類型檢查使用 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: "余弦級數(shù)")] 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) 個主題,數(shù)學包含 \(mathsCount) 個主題")
以上程序執(zhí)行輸出結(jié)果為:
實例物理學是: 固體物理 實例方程式: 赫茲 實例物理學是: 流體動力學 實例公式是: 千兆赫 化學科目包含 2 個主題,數(shù)學包含 3 個主題
向下轉(zhuǎn)型
向下轉(zhuǎn)型,用類型轉(zhuǎn)換操作符(as? 或 as!)
當你不確定向下轉(zhuǎn)型可以成功時,用類型轉(zhuǎn)換的條件形式(as?)。條件形式的類型轉(zhuǎn)換總是返回一個可選值(optional value),并且若下轉(zhuǎn)是不可能的,可選值將是 nil。
只有你可以確定向下轉(zhuǎn)型一定會成功時,才使用強制形式(as!)。當你試圖向下轉(zhuǎn)型為一個不正確的類型時,強制形式的類型轉(zhuǎn)換會觸發(fā)一個運行時錯誤。
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: "余弦級數(shù)")] 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 { // 類型轉(zhuǎn)換的條件形式 if let show = item as? Chemistry { print("化學主題是: '\(show.physics)', \(show.equations)") // 強制形式 } else if let example = item as? Maths { print("數(shù)學主題是: '\(example.physics)', \(example.formulae)") } }
以上程序執(zhí)行輸出結(jié)果為:
實例物理學是: 固體物理 實例方程式: 赫茲 實例物理學是: 流體動力學 實例公式是: 千兆赫 化學主題是: '固體物理', 赫茲 數(shù)學主題是: '流體動力學', 千兆赫 化學主題是: '熱物理學', 分貝 數(shù)學主題是: '天體物理學', 兆赫 數(shù)學主題是: '微分方程', 余弦級數(shù)
Any和AnyObject的類型轉(zhuǎn)換
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: "余弦級數(shù)")] 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 { // 類型轉(zhuǎn)換的條件形式 if let show = item as? Chemistry { print("化學主題是: '\(show.physics)', \(show.equations)") // 強制形式 } else if let example = item as? Maths { print("數(shù)學主題是: '\(example.physics)', \(example.formulae)") } } // 可以存儲Any類型的數(shù)組 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") } }
以上程序執(zhí)行輸出結(jié)果為:
實例物理學是: 固體物理 實例方程式: 赫茲 實例物理學是: 流體動力學 實例公式是: 千兆赫 化學主題是: '固體物理', 赫茲 數(shù)學主題是: '流體動力學', 千兆赫 化學主題是: '熱物理學', 分貝 數(shù)學主題是: '天體物理學', 兆赫 數(shù)學主題是: '微分方程', 余弦級數(shù) 整型值為 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] 類型的數(shù)組 let saprint: [AnyObject] = [ Chemistry(physics: "固體物理", equations: "赫茲"), Maths(physics: "流體動力學", formulae: "千兆赫"), Chemistry(physics: "熱物理學", equations: "分貝"), Maths(physics: "天體物理學", formulae: "兆赫"), Maths(physics: "微分方程", formulae: "余弦級數(shù)")] 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 { // 類型轉(zhuǎn)換的條件形式 if let show = item as? Chemistry { print("化學主題是: '\(show.physics)', \(show.equations)") // 強制形式 } else if let example = item as? Maths { print("數(shù)學主題是: '\(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") } }
以上程序執(zhí)行輸出結(jié)果為:
實例物理學是: 固體物理 實例方程式: 赫茲 實例物理學是: 流體動力學 實例公式是: 千兆赫 化學主題是: '固體物理', 赫茲 數(shù)學主題是: '流體動力學', 千兆赫 化學主題是: '熱物理學', 分貝 數(shù)學主題是: '天體物理學', 兆赫 數(shù)學主題是: '微分方程', 余弦級數(shù) 整型值為 12 Pi 值為 3.14159 Any 實例 主題 '固體物理', 兆赫
在一個switch語句的case中使用強制形式的類型轉(zhuǎn)換操作符(as, 而不是 as?)來檢查和轉(zhuǎn)換到一個明確的類型。
更多建議: