Swift 可選項

  • 可選項,也叫做可選類型蕊温。定義為可選類型后,可以設(shè)置為 nil
  • 在類型名后面加個問號?來定義可選類型
  • 可選類型如果不初始化蝌麸,則默認為nil
var name : String?  /*等同于*/ var name : String? = nil

1. 強制解包

  • 可選項是對其它類型的一種包裝拔第,可以將它理解為一個盒子
  • 如果為 nil咕村,那么它就是一個空盒子
  • 如果不為 nil ,那么盒子里包裝的是:被包裝類型的數(shù)據(jù)
var name : String? = nil

let arr = ["jack","uzi","godV","rookie"]
func getObj(index:Int) -> String?{
    if index<0 || index >= arr.count {
        return nil
    }else{
        return arr[index]
    }
}

print(name)
print(getObj(index: 3))
/*
nil
Optional("rookie")
*/
  • 如果要從可選項中取出被包裝的數(shù)據(jù)蚊俺,則需要使用感嘆號 !進行強制解包
  • 如果對值為nil的可選項進行強制解包懈涛,將會產(chǎn)生運行時錯誤
    錯誤信息:Fatal error: Unexpectedly found nil while unwrapping an Optional value

2. 可選綁定

  • 可以使用 可選項綁定 來判斷可選項是否包含值
  • 如果包含就自動解包,把值賦給一個臨時的常量 或者 變量泳猬,并返回true批钠,否則返回 false
let num = Int("123") 
print(num)//Optional(123)

if let num = Int("123"){
    print("num:",num)//num: 123

}else{
    print("字符串轉(zhuǎn)換失敗")
}

3. if 中的可選綁定

可選項在進行 與(&&) 運算時。不能直接使用 &&得封,可以用逗號分隔的方式
如下:

if let a = Int("12") {
    if let b = Int("44") {
        if a < b && b < 100 {
            print("\(a) < \(b) < 100")
        }
    }
}

//等同于

if let a = Int("12"),
   let b = Int("44"),
    a < b && b < 100{
    print("\(a) < \(b) < 100")

}

3. while 中的可選綁定

//遍歷數(shù)組埋心,進行累加,如果遇到非數(shù)字忙上,停止遍歷
var strs = ["1","2","-3","3","4","5",]
var index:Int = 0
var sum:Int = 0


while
    index < strs.count,
    let obj = Int(strs[index]){
        sum += obj
        index += 1
}
print("sum:",sum)//12

4 ?? 空合并運算符

示例:a ?? b

a:必須是可選項
b:可選項 或者 不是可選項
b跟a的存儲類型必須相同

  • 如果 a 不為 nil踩窖,則返回 a
  • 如果 a 為 nil, 則返回b
  • 如果b不是可選項晨横,返回 a 時洋腮,則a會自動解包
let a: Int? = 1
let b: Int? = 2
let c: Int = 3

let d: Int? = nil

print(a ?? b, a ?? c, d ?? b) //Optional(1) 1 Optional(2)
4.1 ?? 跟if let 配合使用
  • 類似于 if v1 != nil || v2 != nil
let v1:Int? = nil
let v2:Int? = 2

if let c = v1 ?? v2{
    print(c)
}
//類似于 if v1 != nil || v2 != nil
  • 類似于 if v1 != nil && v2 != nil
let v1:Int? = nil
let v2:Int? = 2
if let c = v1,
   let d = v2{
    print("result_c:",c)
    print("result_d:",d)

}

5. guard 語句

guard 條件 else{
   //退出當(dāng)前作用域
} 
  • 當(dāng) guard 語句的條件為 false 時, 就會執(zhí)行大括號里的代碼
  • 當(dāng) guard 語句的條件為true時手形,就會調(diào)過 guard
  • guard 語句特別適合用來 "提前退出"

注意:當(dāng)使用guard 語句進行可選綁定時啥供,可選綁定的常量(let)、變量(var)也能在外層作用域中使用

func login(_ info:[String : String]) -> Bool {
    guard let username = info["username"] else{
        print("用戶名不能為空")

        return false
    }
    guard let password = info["password"] else{
        print("用戶密碼不能為空")
        return false
    }
    print("登錄中 username:\(username)  password:\(password)")
    return false
}
login(["password" : "12345678"])//用戶名不能為空
login(["username" : "Jack"])//用戶密碼不能為空
login(["username" : "Jack", "password" : "12345678"])//登錄中 username:Jack  password:12345678

對比使用 if-else 更加簡便

func login2(_ info:[String : String]) -> Bool {
    let username:String
    
    if let tempUsername = info["username"] {
        username = tempUsername
    }else{
        print("用戶名不能為空")
        return false
    }
    
    let password:String
    if let tempPassword = info["password"] {
        password = tempPassword
    }else{
        print("用戶密碼不能為空")
        return false
    }
    
    print("登錄中 username:\(username)  password:\(password)")

    return true
}

6. 隱式解包

  • 在某些情況下库糠,可選項一旦誒設(shè)定后伙狐,就會一直擁有值
  • 這種情況下,可以去掉檢查瞬欧,也不必每次訪問的時候都進行解包贷屎,因為它能夠確定每次訪問的時候都有值
  • 可以在類型后面加感嘆號!定義一個隱式解包的可選項, 其值不能為 nil
let num1 :Int! = 1  //雖然是隱式解包艘虎,但其仍是可選項
let num2 :Int = num1 //隱式解包可以直接賦值給Int類型

if let k = num1 {
    print(k)
}else{
    print("nil")
}

7. 多重可選項

結(jié)構(gòu)分析
注意:可以使用lldb指令:frame variable -R或者 fr v -R查看區(qū)別

序號 情況1 情況2
1 var n1 : Int? = 10 var n1 : Int? = nil
2 var n2 : Int?? = n1 var n2 : Int?? = n1
3 var n3 : Int?? = 10 var n3 : Int?? = nil

對于情況1:

var n1 : Int?  = 10
var n2 : Int?? = n1
var n3 : Int?? = 10
情況1.png
情況1.png

對于情況2:

var n1 : Int?  = nil
var n2 : Int?? = n1
var n3 : Int?? = nil
情況2.png

情況2.png

分析:個人覺得??
1. 可選類型 some/none {...}中的內(nèi)容即為盒子里的內(nèi)容唉侄。
2. none 標(biāo)識的是空盒子,當(dāng)為空盒子時野建。下層{}也就不存在意義
3. 對于情況2中 n1 n3都為空盒子属划;n2不是空盒子,盒子里有內(nèi)容候生,內(nèi)容為空

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末同眯,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子唯鸭,更是在濱河造成了極大的恐慌须蜗,老刑警劉巖,帶你破解...
    沈念sama閱讀 210,978評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異明肮,居然都是意外死亡菱农,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評論 2 384
  • 文/潘曉璐 我一進店門晤愧,熙熙樓的掌柜王于貴愁眉苦臉地迎上來大莫,“玉大人蛉腌,你說我怎么就攤上這事官份。” “怎么了烙丛?”我有些...
    開封第一講書人閱讀 156,623評論 0 345
  • 文/不壞的土叔 我叫張陵舅巷,是天一觀的道長。 經(jīng)常有香客問我河咽,道長钠右,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,324評論 1 282
  • 正文 為了忘掉前任忘蟹,我火速辦了婚禮飒房,結(jié)果婚禮上糊昙,老公的妹妹穿的比我還像新娘揭鳞。我一直安慰自己,他們只是感情好靴拱,可當(dāng)我...
    茶點故事閱讀 65,390評論 5 384
  • 文/花漫 我一把揭開白布褥芒。 她就那樣靜靜地躺著嚼松,像睡著了一般。 火紅的嫁衣襯著肌膚如雪锰扶。 梳的紋絲不亂的頭發(fā)上献酗,一...
    開封第一講書人閱讀 49,741評論 1 289
  • 那天,我揣著相機與錄音坷牛,去河邊找鬼罕偎。 笑死,一個胖子當(dāng)著我的面吹牛京闰,可吹牛的內(nèi)容都是我干的锨亏。 我是一名探鬼主播,決...
    沈念sama閱讀 38,892評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼忙干,長吁一口氣:“原來是場噩夢啊……” “哼器予!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起捐迫,我...
    開封第一講書人閱讀 37,655評論 0 266
  • 序言:老撾萬榮一對情侶失蹤乾翔,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體反浓,經(jīng)...
    沈念sama閱讀 44,104評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡萌丈,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了雷则。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片辆雾。...
    茶點故事閱讀 38,569評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖月劈,靈堂內(nèi)的尸體忽然破棺而出度迂,到底是詐尸還是另有隱情,我是刑警寧澤猜揪,帶...
    沈念sama閱讀 34,254評論 4 328
  • 正文 年R本政府宣布惭墓,位于F島的核電站,受9級特大地震影響而姐,放射性物質(zhì)發(fā)生泄漏腊凶。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,834評論 3 312
  • 文/蒙蒙 一拴念、第九天 我趴在偏房一處隱蔽的房頂上張望钧萍。 院中可真熱鬧,春花似錦政鼠、人聲如沸风瘦。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽弛秋。三九已至,卻和暖如春俐载,著一層夾襖步出監(jiān)牢的瞬間蟹略,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評論 1 264
  • 我被黑心中介騙來泰國打工遏佣, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留挖炬,地道東北人。 一個月前我還...
    沈念sama閱讀 46,260評論 2 360
  • 正文 我出身青樓状婶,卻偏偏與公主長得像意敛,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子膛虫,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,446評論 2 348