[Swift2.0系列]新的匹配解包方式(初稿)

Optional Pattern

更新歷史:

  1. 2015.10.31新增case-let其他寫法

當(dāng)變量存在值有可能缺失的情況下使用可選類型,官方文檔如下定義:

  • There is a value ,and it equals x,值存在且等于x.
  • There isn't a value at all,值不存在!

本文今天不涉及基礎(chǔ)語(yǔ)法,更多有關(guān)可選類型的內(nèi)容,請(qǐng)看Why coding like this--自己創(chuàng)建一個(gè)可選類型一文。

Swift1.2和Swift2.0 解包方式

Swift1.2

早前我們都喜歡使用if-let或者??進(jìn)行可選類型進(jìn)行解包,形如:

//這是一個(gè)整數(shù)可選類型
let someOptional:Int? = 42   //你可以改成nil試試 會(huì)發(fā)現(xiàn)沒(méi)有輸出了

//以前的解包方式
if let x = someOptional{
  print("someOptional value is \(x)")
}
var y = someOptional ?? 4

Swift2.0

而如今,Swift2.0又一次創(chuàng)新,新增如下兩種方式。不如先一睹風(fēng)采:

//1
//新增使用enumeration匹配 也就是枚舉匹配方式
if case .Some(let x) = someOptional{
  print("someOptional value is \(x)") //如果為nil 情況 可不會(huì)輸出東西 因?yàn)槠ヅ涞氖荢ome!
}
//2
//新增使用可選模式匹配

if case let x? = someOptional{
  print("someOptional value is \(x)") //不需要對(duì)x進(jìn)行解包之類的東東
}

可選類型是一個(gè)枚舉,存在case None 以及 case Some(T)兩種情況,其中T是包裹的值。

對(duì)于case .Some(let x) = someOptional這種匹配模式,右邊的someOptional是一個(gè)可選類型,完整定義是:let someOptional:Int? = 42,換種方式寫成case .Some(42)顯然兩者是匹配的,那么順?biāo)浦郯?code>x = 42嘍。倘若someOptional = nil了呢?依舊轉(zhuǎn)換成case .None,這時(shí)候左右兩邊是不匹配的! 有關(guān)更多匹配文章,請(qǐng)見(jiàn)swift.gg站點(diǎn)文章。

對(duì)于case let x? 其實(shí)和case .Some(let x)是一個(gè)道理。

兩種解包優(yōu)勢(shì)在哪里?

有人問(wèn)if-let解包 和 if case let x? 解包有什么區(qū)別?說(shuō)實(shí)話,博主目前也不清楚。希望有人告知,-。

這并不意味著if case let x?沒(méi)有存在的價(jià)值,例如

let arrayOptionalInts:[Int?] = [nil,1,2,3,nil,5]    //數(shù)組的類型是Int? 可選類型嘍

//遍歷是用for-in  
//swift 1.2寫法

for x in arrayOptionalInts{
  if let y = x{
    print("Found a \(y)")//把非 nil 值輸出來(lái)
  }
}

//swift 2.0寫法
//把解包行為提前到for 語(yǔ)句中了
for case let number? in arrayOptionalInts{
  print("Found a \(number)")
}

有對(duì)比才有發(fā)現(xiàn),確實(shí)這時(shí)候新語(yǔ)法更勝一籌。

拓展

下面我寫了一個(gè)小例子,以角色游戲?yàn)楸尘?,游戲中有玩家、NPC和怪物。如下聲明:

// 游戲角色 有玩家 NPC 怪獸
enum GameRole{
    case Player(name:String)// 玩家要有名字
    case NPC(name:String,faction:String)//名字 所屬陣營(yíng)
    case Monster(name:String,element:Int)//怪物名字 屬性 水火金木土 對(duì)應(yīng)1-5
}


var roles = [
    GameRole.Player(name: "玩家一"),
    GameRole.Player(name: "玩家二"),
    GameRole.Player(name: "玩家三"),
    GameRole.Player(name: "玩家四"),
    GameRole.NPC(name: "NPC1", faction: "光明"),
    GameRole.NPC(name: "NPC2", faction: "黑暗"),
    GameRole.NPC(name: "NPC3", faction: "精靈"),
    GameRole.NPC(name: "NPC4", faction: "黑暗"),
    GameRole.Monster(name: "怪物1", element: 1),
    GameRole.Monster(name: "怪物2", element: 2),
    GameRole.Monster(name: "怪物3", element: 4),
    GameRole.Monster(name: "怪物4", element: 5),
]

// 早前使用方法
// 遍歷整個(gè)角色
for role in roles{
    // 因?yàn)槭敲杜e 所以要switch來(lái)匹配
    switch role{
    case .NPC:
        print("有 NPC 出沒(méi)")
    default:
        break
    }
}

可以看到想要遍歷所有roles中的NPC 比如先用for-in循環(huán),隨后再用switch來(lái)進(jìn)行匹配找到NPC。代碼過(guò)于冗余,甚是不爽啊。好在Swift2.0中引入的case let解包方式,以下會(huì)讓你耳目一新:

for case .NPC in roles{
    print("NPC找到")
}

倘若我還想要NPC中關(guān)聯(lián)的名字以及陣營(yíng)呢?

for case let .NPC(name,faction) in roles{
    print("NPC找到 name:\(name) 陣營(yíng):\(faction)")
}

苛刻一點(diǎn) 我只想要黑暗陣營(yíng)的NPC!

for case let .NPC(name,faction) in roles where faction == "黑暗"{
    print("NPC找到 name:\(name) 陣營(yíng):\(faction)")
}

恩.可能你還看不慣case-let這種寫法,或許你對(duì)其還是無(wú)感。但是我若是這么寫呢?

(2015.10.31更新)

for case .NPC(let  name, let  faction) in roles where faction == "黑暗"{
    print("NPC找到 name:\(name) 陣營(yíng):\(faction)")
}

如此純正的枚舉匹配,為此你還有疑惑? 倘若需要自定義匹配模式,需要重載func ~=(pattern:value)這一方法。

倘若你覺(jué)得文章不錯(cuò),請(qǐng)關(guān)注我,點(diǎn)擊喜歡。另外推薦swift技術(shù)群:392436022。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容