第二十六章 Swift 類(lèi)型轉(zhuǎn)換

Swift 語(yǔ)言類(lèi)型轉(zhuǎn)換可以判斷實(shí)例的類(lèi)型趣席。也可以用于檢測(cè)實(shí)例類(lèi)型是否屬于其父類(lèi)或者子類(lèi)的實(shí)例,或是否實(shí)現(xiàn)了某個(gè)協(xié)議。

Swift 中類(lèi)型轉(zhuǎn)換使用 isas 操作符實(shí)現(xiàn)杂曲,is 用于檢測(cè)值的類(lèi)型诈火,as 用于轉(zhuǎn)換類(lèi)型兽赁。

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: "流體動(dòng)力學(xué)", formulae: "千兆赫")]


let samplechem = Chemistry(physics: "固體物理", equations: "赫茲")
print("實(shí)例物理學(xué)是: \(samplechem.physics)")
print("實(shí)例方程式: \(samplechem.equations)")


let samplemaths = Maths(physics: "流體動(dòng)力學(xué)", formulae: "千兆赫")
print("實(shí)例物理學(xué)是: \(samplemaths.physics)")
print("實(shí)例公式是: \(samplemaths.formulae)")

// 實(shí)例物理學(xué)是: 固體物理
// 實(shí)例方程式: 赫茲
// 實(shí)例物理學(xué)是: 流體動(dòng)力學(xué)
// 實(shí)例公式是: 千兆赫

1. 檢查類(lèi)型

類(lèi)型檢查使用is關(guān)鍵字,用于檢測(cè)實(shí)例類(lèi)型是否屬于特定的實(shí)例類(lèi)型冷守。

你可以將它用在類(lèi)和子類(lèi)的層次結(jié)構(gòu)上刀崖,檢查特定類(lèi)實(shí)例的類(lèi)型并且轉(zhuǎn)換這個(gè)類(lèi)實(shí)例的類(lèi)型成為這個(gè)層次結(jié)構(gòu)中的其他類(lèi)型。

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: "流體動(dòng)力學(xué)", formulae: "千兆赫"),
    Chemistry(physics: "熱物理學(xué)", equations: "分貝"),
    Maths(physics: "天體物理學(xué)", formulae: "兆赫"),
    Maths(physics: "微分方程", formulae: "余弦級(jí)數(shù)")]


let samplechem = Chemistry(physics: "固體物理", equations: "赫茲")
print("實(shí)例物理學(xué)是: \(samplechem.physics)")
print("實(shí)例方程式: \(samplechem.equations)")


let samplemaths = Maths(physics: "流體動(dòng)力學(xué)", formulae: "千兆赫")
print("實(shí)例物理學(xué)是: \(samplemaths.physics)")
print("實(shí)例公式是: \(samplemaths.formulae)")

var chemCount = 0
var mathsCount = 0
for item in sa {
    // 如果是一個(gè) Chemistry 類(lèi)型的實(shí)例拍摇,返回 true亮钦,相反返回 false。
    if item is Chemistry {
        ++chemCount
    } else if item is Maths {
        ++mathsCount
    }
}

print("化學(xué)科目包含 \(chemCount) 個(gè)主題授翻,數(shù)學(xué)包含 \(mathsCount) 個(gè)主題")

// 實(shí)例物理學(xué)是: 固體物理
// 實(shí)例方程式: 赫茲
// 實(shí)例物理學(xué)是: 流體動(dòng)力學(xué)
// 實(shí)例公式是: 千兆赫
// 化學(xué)科目包含 2 個(gè)主題或悲,數(shù)學(xué)包含 3 個(gè)主題

2. 向下轉(zhuǎn)型

向下轉(zhuǎn)型,用類(lèi)型轉(zhuǎn)換操作符:as as? as!

as 系統(tǒng)中的大多數(shù)的CF對(duì)象可以使用as直接轉(zhuǎn)換為Swift類(lèi)型
as? 當(dāng)你不確定向下轉(zhuǎn)型可以成功時(shí)堪唐,用類(lèi)型轉(zhuǎn)換的條件形式as?巡语。條件形式的類(lèi)型轉(zhuǎn)換總是返回一個(gè)可選值,并且若下轉(zhuǎn)是不可能的淮菠,可選值將是 nil男公。
as! 只有你可以確定向下轉(zhuǎn)型一定會(huì)成功時(shí),才使用強(qiáng)制形式as!合陵。當(dāng)你試圖向下轉(zhuǎn)型為一個(gè)不正確的類(lèi)型時(shí)枢赔,強(qiáng)制形式的類(lèi)型轉(zhuǎn)換會(huì)觸發(fā)一個(gè)運(yùn)行時(shí)錯(cuò)誤。
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: "流體動(dòng)力學(xué)", formulae: "千兆赫"),
    Chemistry(physics: "熱物理學(xué)", equations: "分貝"),
    Maths(physics: "天體物理學(xué)", formulae: "兆赫"),
    Maths(physics: "微分方程", formulae: "余弦級(jí)數(shù)")]


let samplechem = Chemistry(physics: "固體物理", equations: "赫茲")
print("實(shí)例物理學(xué)是: \(samplechem.physics)")
print("實(shí)例方程式: \(samplechem.equations)")


let samplemaths = Maths(physics: "流體動(dòng)力學(xué)", formulae: "千兆赫")
print("實(shí)例物理學(xué)是: \(samplemaths.physics)")
print("實(shí)例公式是: \(samplemaths.formulae)")

var chemCount = 0
var mathsCount = 0

for item in sa {
    // 類(lèi)型轉(zhuǎn)換的條件形式
    if let show = item as? Chemistry {
        print("化學(xué)主題是: '\(show.physics)', \(show.equations)")
        // 強(qiáng)制形式
    } else if let example = item as? Maths {
        print("數(shù)學(xué)主題是: '\(example.physics)',  \(example.formulae)")
    }
}

/*
實(shí)例物理學(xué)是: 固體物理
實(shí)例方程式: 赫茲
實(shí)例物理學(xué)是: 流體動(dòng)力學(xué)
實(shí)例公式是: 千兆赫
化學(xué)主題是: '固體物理', 赫茲
數(shù)學(xué)主題是: '流體動(dòng)力學(xué)',  千兆赫
化學(xué)主題是: '熱物理學(xué)', 分貝
數(shù)學(xué)主題是: '天體物理學(xué)',  兆赫
數(shù)學(xué)主題是: '微分方程',  余弦級(jí)數(shù)
*/

3. Any和AnyObject的類(lèi)型轉(zhuǎn)換

OC中的id類(lèi)型在Swift中使用AnyObject拥知,Swift為不確定類(lèi)型提供了兩種特殊類(lèi)型別名:

  • AnyObject可以代表任何class類(lèi)型的實(shí)例踏拜。
  • Any可以表示任何類(lèi)型,包括基本類(lèi)型(Int Double)低剔、方法類(lèi)型(function types)速梗、枚舉結(jié)構(gòu)體肮塞、指針等。

Any 實(shí)例

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: "流體動(dòng)力學(xué)", formulae: "千兆赫"),
    Chemistry(physics: "熱物理學(xué)", equations: "分貝"),
    Maths(physics: "天體物理學(xué)", formulae: "兆赫"),
    Maths(physics: "微分方程", formulae: "余弦級(jí)數(shù)")]


let samplechem = Chemistry(physics: "固體物理", equations: "赫茲")
print("實(shí)例物理學(xué)是: \(samplechem.physics)")
print("實(shí)例方程式: \(samplechem.equations)")


let samplemaths = Maths(physics: "流體動(dòng)力學(xué)", formulae: "千兆赫")
print("實(shí)例物理學(xué)是: \(samplemaths.physics)")
print("實(shí)例公式是: \(samplemaths.formulae)")

var chemCount = 0
var mathsCount = 0

for item in sa {
    // 類(lèi)型轉(zhuǎn)換的條件形式
    if let show = item as? Chemistry {
        print("化學(xué)主題是: '\(show.physics)', \(show.equations)")
        // 強(qiáng)制形式
    } else if let example = item as? Maths {
        print("數(shù)學(xué)主題是: '\(example.physics)',  \(example.formulae)")
    }
}

// 可以存儲(chǔ)Any類(lèi)型的數(shù)組 exampleany
var exampleany = [Any]()

exampleany.append(12)
exampleany.append(3.14159)
exampleany.append("Any 實(shí)例")
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")
    }
}

/*
實(shí)例物理學(xué)是: 固體物理
實(shí)例方程式: 赫茲
實(shí)例物理學(xué)是: 流體動(dòng)力學(xué)
實(shí)例公式是: 千兆赫
化學(xué)主題是: '固體物理', 赫茲
數(shù)學(xué)主題是: '流體動(dòng)力學(xué)',  千兆赫
化學(xué)主題是: '熱物理學(xué)', 分貝
數(shù)學(xué)主題是: '天體物理學(xué)',  兆赫
數(shù)學(xué)主題是: '微分方程',  余弦級(jí)數(shù)
整型值為 12
Pi 值為 3.14159
Any 實(shí)例
主題 '固體物理', 兆赫
*/

AnyObject 實(shí)例

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] 類(lèi)型的數(shù)組
let saprint: [AnyObject] = [
    Chemistry(physics: "固體物理", equations: "赫茲"),
    Maths(physics: "流體動(dòng)力學(xué)", formulae: "千兆赫"),
    Chemistry(physics: "熱物理學(xué)", equations: "分貝"),
    Maths(physics: "天體物理學(xué)", formulae: "兆赫"),
    Maths(physics: "微分方程", formulae: "余弦級(jí)數(shù)")]


let samplechem = Chemistry(physics: "固體物理", equations: "赫茲")
print("實(shí)例物理學(xué)是: \(samplechem.physics)")
print("實(shí)例方程式: \(samplechem.equations)")


let samplemaths = Maths(physics: "流體動(dòng)力學(xué)", formulae: "千兆赫")
print("實(shí)例物理學(xué)是: \(samplemaths.physics)")
print("實(shí)例公式是: \(samplemaths.formulae)")

var chemCount = 0
var mathsCount = 0

for item in saprint {
    // 類(lèi)型轉(zhuǎn)換的條件形式
    if let show = item as? Chemistry {
        print("化學(xué)主題是: '\(show.physics)', \(show.equations)")
        // 強(qiáng)制形式
    } else if let example = item as? Maths {
        print("數(shù)學(xué)主題是: '\(example.physics)',  \(example.formulae)")
    }
}

var exampleany = [Any]()
exampleany.append(12)
exampleany.append(3.14159)
exampleany.append("Any 實(shí)例")
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")
    }
}

/*
實(shí)例物理學(xué)是: 固體物理
實(shí)例方程式: 赫茲
實(shí)例物理學(xué)是: 流體動(dòng)力學(xué)
實(shí)例公式是: 千兆赫
化學(xué)主題是: '固體物理', 赫茲
數(shù)學(xué)主題是: '流體動(dòng)力學(xué)',  千兆赫
化學(xué)主題是: '熱物理學(xué)', 分貝
數(shù)學(xué)主題是: '天體物理學(xué)',  兆赫
數(shù)學(xué)主題是: '微分方程',  余弦級(jí)數(shù)
整型值為 12
Pi 值為 3.14159
Any 實(shí)例
主題 '固體物理', 兆赫
*/

在一個(gè)switch語(yǔ)句的case中使用強(qiáng)制形式的類(lèi)型轉(zhuǎn)換操作符as(而不是 as?)來(lái)檢查和轉(zhuǎn)換到一個(gè)明確的類(lèi)型(這是模式匹配姻锁,將在其他章節(jié)講解枕赵,這里記住如何使用即可)。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末位隶,一起剝皮案震驚了整個(gè)濱河市拷窜,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌涧黄,老刑警劉巖篮昧,帶你破解...
    沈念sama閱讀 221,576評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異弓熏,居然都是意外死亡恋谭,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,515評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén)挽鞠,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)疚颊,“玉大人,你說(shuō)我怎么就攤上這事信认〔囊澹” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,017評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵嫁赏,是天一觀的道長(zhǎng)其掂。 經(jīng)常有香客問(wèn)我,道長(zhǎng)潦蝇,這世上最難降的妖魔是什么款熬? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,626評(píng)論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮攘乒,結(jié)果婚禮上贤牛,老公的妹妹穿的比我還像新娘。我一直安慰自己则酝,他們只是感情好殉簸,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,625評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著沽讹,像睡著了一般般卑。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上爽雄,一...
    開(kāi)封第一講書(shū)人閱讀 52,255評(píng)論 1 308
  • 那天蝠检,我揣著相機(jī)與錄音,去河邊找鬼挚瘟。 笑死叹谁,一個(gè)胖子當(dāng)著我的面吹牛迟杂,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播本慕,決...
    沈念sama閱讀 40,825評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼侧漓!你這毒婦竟也來(lái)了锅尘?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,729評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤布蔗,失蹤者是張志新(化名)和其女友劉穎藤违,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體纵揍,經(jīng)...
    沈念sama閱讀 46,271評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡顿乒,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,363評(píng)論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了泽谨。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片璧榄。...
    茶點(diǎn)故事閱讀 40,498評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖吧雹,靈堂內(nèi)的尸體忽然破棺而出骨杂,到底是詐尸還是另有隱情,我是刑警寧澤雄卷,帶...
    沈念sama閱讀 36,183評(píng)論 5 350
  • 正文 年R本政府宣布搓蚪,位于F島的核電站,受9級(jí)特大地震影響丁鹉,放射性物質(zhì)發(fā)生泄漏妒潭。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,867評(píng)論 3 333
  • 文/蒙蒙 一揣钦、第九天 我趴在偏房一處隱蔽的房頂上張望雳灾。 院中可真熱鬧,春花似錦拂盯、人聲如沸佑女。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,338評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)团驱。三九已至,卻和暖如春空凸,著一層夾襖步出監(jiān)牢的瞬間嚎花,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,458評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工呀洲, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留紊选,地道東北人啼止。 一個(gè)月前我還...
    沈念sama閱讀 48,906評(píng)論 3 376
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像兵罢,于是被迫代替她去往敵國(guó)和親献烦。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,507評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容