可選值

一歌径、 基本概念

  1. 變量,類型亲茅,初始化
var str: String
str = "Hello World"
str.uppercaseString   
var str2: String = "Hello World2"
  1. 類型推斷沮脖,強(qiáng)類型
var str3 = "Hello World3"
  1. 可選類型,枚舉
//Optional<Sting>
var errorCodeString: String?
errorCodeString = "404"
errorCodeString = nil
  • 強(qiáng)制解包發(fā)現(xiàn)為nil導(dǎo)致運(yùn)行時(shí)崩潰,不安全芯急!
 let theError: String = errorCodeString!
  1. if 語(yǔ)句
if errorCodeString != nil {
    let theError = errorCodeString!
}
  1. 可選綁定
if let theError = errorCodeString {
}
  1. 可選綁定嵌套,"Pyramid of Doom"
if let theError = errorCodeString {
    if let errorCodeInteger = Int(theError) {
        if errorCodeInteger == 404 {
        print("\(theError): \(errorCodeInteger)")
        }
    }
}
  1. 簡(jiǎn)化驶俊,都不為nil時(shí)執(zhí)行娶耍。where相當(dāng)于if判斷語(yǔ)句
if let theError = errorCodeString, errorCodeInteger = Int(theError) where errorCodeInteger == 404 {
    print("\(theError): \(errorCodeInteger)")
}

4 .隱式解包的可選 -- 不安全!

var errorCodeString2: String!
errorCodeString2 = "404"
errorCodeString2 = nil
  • 如果為nil饼酿,導(dǎo)致運(yùn)行時(shí)崩潰,不安全榕酒!
let theError2: String = errorCodeString2
  • 萬(wàn)能的 if, 可選綁定
if errorCodeString2 != nil {
    let theError2: String = errorCodeString2
}
if let theError2 = errorCodeString2 {
    print(theError2)
}

注意:
如果一個(gè)變量之后可能變成nil的話請(qǐng)不要使用隱式解包的可選類型。
如果你需要在變量的生命周期中判斷是否是nil的話故俐,請(qǐng)使用普通可選類型想鹰。

二、安全地使用可選值

  1. Swift 的可選類型可以?來(lái)表?可能缺失或是計(jì)算失敗的值药版。
let cities = ["Paris": 2241, "Madrid": 3165, "Amsterdam": 827, "Berlin": 3562]
let madridPopulation: Int? = cities["Madrid"]
if madridPopulation != nil {
    print ("The population of Madrid is \(madridPopulation! * 1000)")
} else {
    print ("Unknown city: Madrid")
}
  1. 可選綁定辑舷,可以讓你避免寫 ! 后綴。不再需要顯式地使?強(qiáng)制解包槽片。
if let madridPopulation = cities["Madrid"] {
    print ("The population of Madrid is \(madridPopulation * 1000)")
} else {
    print ("Unknown city: Madrid")
}
  1. 空合運(yùn)算符
let madridPopulationValue: Int
if madridPopulation != nil {
 madridPopulationValue = madridPopulation!
} else {
 madridPopulationValue = 1000
}
//a != nil ? a! : b
//a ?? b
let madridPopulationValue2 = madridPopulation != nil ? madridPopulation! : 1000
let madridPopulationValue3 = madridPopulation ?? 1000
// autoclosure 類型標(biāo)簽來(lái)避開(kāi)創(chuàng)建顯式閉包 myOptional ?? myDefaultValue -> myOptional ?? { myDefaultValue }
  1. 可選鏈
    可選鏈?zhǔn)秸{(diào)用(Optional Chaining)是一種可以在當(dāng)前值可能為nil的可選值上請(qǐng)求和調(diào)用屬性何缓、方法及下標(biāo)的方法。如果可選值有值还栓,那么調(diào)用就會(huì)成功碌廓;如果可選值是nil,那么調(diào)用將返回nil剩盒。多個(gè)調(diào)用可以連接在一起形成一個(gè)調(diào)用鏈谷婆,如果其中任何一個(gè)節(jié)點(diǎn)為nil,整個(gè)調(diào)用鏈都會(huì)失敗辽聊,即返回nil纪挎。
struct Order {
    let orderNumber: Int
    let person: Person?
}
struct Person {
    let name: String
    let address: Address?
}
struct Address {
    let streetName: String
    let city : String
    let state: String?
}
let order = Order(orderNumber: 1, person: nil)
// order.person!.address!.state!
if let myPerson = order.person {
    if let myAddress = myPerson.address {
        if let myState = myAddress.state {
        }
}
}
  • 使?問(wèn)號(hào)運(yùn)算符來(lái)嘗試對(duì)可選類型進(jìn)?解包。當(dāng)任意?個(gè)組成項(xiàng)失敗時(shí)身隐,整條語(yǔ)句鏈將返回 nil廷区。
if let myState = order.person?.address?.state {
    print ("This order will be shipped to \(myState)")
} else {
    print ("Unknown person, address, or state.")
}
  1. 分支上的可選值
  • switch 語(yǔ)句
switch madridPopulation {
case 0?: print ("Nobody in Madrid")
case (1..<1000)?: print ("Less than a million in Madrid")
case .Some(let x): print ("\(x) people in Madrid")
case .None: print("We don't know about Madrid")  
}
  1. guard 語(yǔ)句: 在當(dāng)?些條件不滿?時(shí),可以盡早退出當(dāng)前作?域,避免不必要的計(jì)算贾铝∠肚幔可以使??可選的 population 值,?嵌套 if let 語(yǔ)句時(shí)更簡(jiǎn)單埠帕。
func populationDescriptionForCity(city: String) -> String? {
    guard city != "madrid" else { return nil }
    if city == "madrid" {
        return nil
    } 
    guard let population = cities[city ] else { return nil }
    return "The population of Madrid is \(population * 1000)"
    if let population = cities[city ] {
        return "The population of Madrid is \(population * 1000)"
    } else {
        return nil
    } 
}
  1. 可選映射 : 若可選值存在,你可能會(huì)想操作它玖绿,否則返回 nil敛瓷。
madridPopulation.map { (<#Int#>) -> U in 
}
madridPopulation.flatMap { (<#Int#>) -> U? in
}
let capitals = [
    "France": "Paris",
    "Spain": "Madrid",
    "The Netherlands": "Amsterdam",
    "Belgium": "Brussels"
]
func populationOfCapital(country: String) -> Int? {
    guard let capital = capitals[country], population = cities[capital]
        else { return nil }
    return population * 1000
}
func populationOfCapital2(country: String) -> Int? {
    return capitals[country].flatMap { capital in
        cities [capital].flatMap { population in
            return population * 1000
        }
    }
}
func populationOfCapital3(country: String) -> Int? {
    return capitals[country].flatMap { capital in
        return cities [capital]
        }.flatMap { population in
            return population * 1000
    }
}
  1. 為什么使用可選值?

強(qiáng)?的類型系統(tǒng)能在代碼執(zhí)?前捕獲到錯(cuò)誤斑匪,?且顯式可選類型有助于避免由缺失值導(dǎo)致的意外崩潰呐籽。

//NSString *someString = ...;
//if ([ someString rangeOfString:@"swift"].location != NSNotFound) {
//    NSLog(@"Someone mentioned swift!");
//}
//
//if let someString = ... {
//if someString.rangeOfString("swift").location != NSNotFound {
//print ("Found")
//}
//}

三、map 和 flatMap 的其他用法

// CollectionType :  SequenceType
// public func map<T>(@noescape transform: (Self.Generator.Element) throws -> T) rethrows -> [T]

// SequenceType
// public func flatMap<S : SequenceType>(transform: (Self.Generator.Element) throws -> S) rethrows -> [S.Generator.Element]
// public func flatMap<T>(@noescape transform: (Self.Generator.Element) throws -> T?) rethrows -> [T]

let numbers = [1,2,3,4]
var result = numbers.map { $0 + 2 }
// [3,4,5,6]
result = numbers.flatMap { $0 + 2 }
// [3,4,5,6]


// s.flatMap(transform) == Array(s.map(transform).flatten())
let numbersCompound = [[1,2,3],[4,5,6]];
var res = numbersCompound.map { $0.map{ $0 + 2 } }
// [[3, 4, 5], [6, 7, 8]]
var flatRes = numbersCompound.flatMap { $0.map{ $0 + 2 } }
// [3, 4, 5, 6, 7, 8]

// s.flatMap(transform) == s.map(transform).filter{ $0 != nil }.map{ $0! }
let optionalArray: [String?] = ["AA", nil, "BB", "CC"];
var optionalResult: [String] = optionalArray.flatMap{ $0 }
// ["AA", "BB", "CC"]
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末蚀瘸,一起剝皮案震驚了整個(gè)濱河市狡蝶,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌贮勃,老刑警劉巖贪惹,帶你破解...
    沈念sama閱讀 211,639評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異寂嘉,居然都是意外死亡奏瞬,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,277評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門泉孩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)硼端,“玉大人,你說(shuō)我怎么就攤上這事寓搬≌渥颍” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 157,221評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵句喷,是天一觀的道長(zhǎng)曼尊。 經(jīng)常有香客問(wèn)我,道長(zhǎng)脏嚷,這世上最難降的妖魔是什么骆撇? 我笑而不...
    開(kāi)封第一講書人閱讀 56,474評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮父叙,結(jié)果婚禮上神郊,老公的妹妹穿的比我還像新娘。我一直安慰自己趾唱,他們只是感情好涌乳,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,570評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著甜癞,像睡著了一般夕晓。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上悠咱,一...
    開(kāi)封第一講書人閱讀 49,816評(píng)論 1 290
  • 那天蒸辆,我揣著相機(jī)與錄音征炼,去河邊找鬼。 笑死躬贡,一個(gè)胖子當(dāng)著我的面吹牛谆奥,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播拂玻,決...
    沈念sama閱讀 38,957評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼酸些,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了檐蚜?” 一聲冷哼從身側(cè)響起魄懂,我...
    開(kāi)封第一講書人閱讀 37,718評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎闯第,沒(méi)想到半個(gè)月后逢渔,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,176評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡乡括,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,511評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了智厌。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片诲泌。...
    茶點(diǎn)故事閱讀 38,646評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖铣鹏,靈堂內(nèi)的尸體忽然破棺而出敷扫,到底是詐尸還是另有隱情,我是刑警寧澤诚卸,帶...
    沈念sama閱讀 34,322評(píng)論 4 330
  • 正文 年R本政府宣布葵第,位于F島的核電站,受9級(jí)特大地震影響合溺,放射性物質(zhì)發(fā)生泄漏卒密。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,934評(píng)論 3 313
  • 文/蒙蒙 一棠赛、第九天 我趴在偏房一處隱蔽的房頂上張望哮奇。 院中可真熱鬧,春花似錦睛约、人聲如沸鼎俘。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,755評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)贸伐。三九已至,卻和暖如春怔揩,著一層夾襖步出監(jiān)牢的瞬間捉邢,已是汗流浹背脯丝。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 31,987評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留歌逢,地道東北人巾钉。 一個(gè)月前我還...
    沈念sama閱讀 46,358評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像秘案,于是被迫代替她去往敵國(guó)和親砰苍。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,514評(píng)論 2 348

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