swift 5.0 可選項(xiàng)

隨著swift語言的不斷發(fā)展,越來越來趨于穩(wěn)定化∽帜現(xiàn)在也有很多公司使用swift來開發(fā)新的App探越,那么不會swift開發(fā)的iOS開發(fā)者在競爭中還是很弱勢的,所有學(xué)習(xí)swift是大勢所趨窑业。本系列文章根據(jù)以往的學(xué)習(xí)積累和項(xiàng)目經(jīng)驗(yàn)钦幔,從基礎(chǔ)到原理詳細(xì)說說swift的這點(diǎn)事兒,不喜勿噴常柄,交流指正請加微信鲤氢。
WeChatdfdb8bfa7f0a84545d010ef18af70a98.png
可選項(xiàng),一般也叫可選類型拐纱,它允許將值設(shè)置為nil
在類型名稱后面加個問號 ? 來定義一個可選項(xiàng)
一. 定義可選項(xiàng)
var name :String? = "Jack"
name = nil
var age : Int?//默認(rèn)就是nii
age = 10
age = nil
二. 返回值是可選項(xiàng)
var array = [1, 15, 40, 29]
func get(_ index: Int) -> Int? {
    if index < 0 || index >= array.count {
        return nil
    }
    return array[index]
}

print(get(1)) // Optional(15)
print(get(-1)) // nil  print(get(4)) // nil

這段代碼就是傳進(jìn)去一個數(shù)組的下標(biāo)铜异,如果取到值了那就返回,取不到就返回nil秸架,所以這個函數(shù)的返回值類型定義為可選項(xiàng)揍庄。

三. 強(qiáng)制解包

可選項(xiàng)是對其他類型的一層包裝,可以將它理解為一個盒子
如果為nil东抹,那么它是個空盒子
如果不為nil蚂子,那么盒子里裝的是:被包裝類型的數(shù)據(jù)

var age: Int? // 默認(rèn)就是nil (1)
age = 10 (2)
age = nil(3)
以上代碼執(zhí)行圖示

代碼第一步未賦值,默認(rèn)為nil缭黔,盒子是空的食茎。第二步,賦值age = 10馏谨,盒子里裝了一個10别渔。第三步設(shè)為nil,盒子又空了。

強(qiáng)制解包概念: 如果要從可選項(xiàng)中取出被包裝的數(shù)據(jù)(將盒子里裝的東西取出來)哎媚,需要使用感嘆號 ! 進(jìn)行強(qiáng)制解包喇伯。
var age: Int? = 10
let ageInt: Int = age!  
ageInt += 10

以上代碼就是聲明了一個可選項(xiàng)age,里面有一個Int類型的數(shù)據(jù)10拨与,age稻据!將可選項(xiàng)里面的值取出來,賦值給ageInt买喧,再給ageInt加10的過程捻悯。

如果對值為nil的可選項(xiàng)(空盒子)進(jìn)行強(qiáng)制解包,將會產(chǎn)生運(yùn)行時錯誤
var age: Int?
let a = age!
Fatal error: Unexpectedly found nil while unwrapping an Optional value
四. 判斷可選項(xiàng)是否包含值
let number = Int("123")
if number != nil {
    print("字符串轉(zhuǎn)換整數(shù)成功:\(number!)")
} else {
    print("字符串轉(zhuǎn)換整數(shù)失敗")
}
// 字符串轉(zhuǎn)換整數(shù)成功:123
五. 可選項(xiàng)綁定
可以使用可選項(xiàng)綁定來判斷可選項(xiàng)是否包含值
如果包含就自動解包淤毛,把值賦給一個臨時的常量(let)或者變量(var)今缚,并返回true,否則返回false
if let number = Int("123") {
    print("字符串轉(zhuǎn)換整數(shù)成功:\(number)")
    // number是強(qiáng)制解包之后的Int值
    // number作用域僅限于這個大括號
    } else {
    print("字符串轉(zhuǎn)換整數(shù)失敗")
}
// 字符串轉(zhuǎn)換整數(shù)成功:123
enum Season : Int {
    case spring = 1, summer, autumn, winter
}
if let season = Season(rawValue: 6) {
    switch season {
        case .spring:
            print("the season is spring")
        default:
            print("the season is other")
    }
} else {
        print("no such season")
}
// no such season
六. 空合并運(yùn)算符 ??
public func ?? <T>(optional: T?, defaultValue: @autoclosure () throws -> T?) rethrows -> T?
public func ?? <T>(optional: T?, defaultValue: @autoclosure () throws -> T) rethrows -> T

a ?? b
a 是可選項(xiàng)
b 是可選項(xiàng) 或者 不是可選項(xiàng)
b 跟 a 的存儲類型必須相同
如果 a 不為nil低淡,就返回 a
如果 a 為nil荚斯,就返回 b
如果 b 不是可選項(xiàng),返回 a 時會自動解包

let a: Int? = 1
let b: Int? = 2
let c = a ?? b // c是Int? , Optional(1)

a查牌,b都是可選項(xiàng)并且a不為nil,所以返回 a

let a: Int? = nil
let b: Int? = 2
let c = a ?? b // c是Int? , Optional(2)

a滥壕,b都是可選項(xiàng)并且a為nil纸颜,所以返回 b

let a: Int? = nil
let b: Int? = nil
let c = a ?? b // c是Int? , nil

a,b都是可選項(xiàng)并且a為nil绎橘,所以返回 b

let a: Int? = 1
let b: Int = 2
let c = a ?? b // c是Int , 1

a是可選項(xiàng),b不是可選項(xiàng)并且a不為nil胁孙,所以返回 a

let a: Int? = nil
let b: Int = 2
let c = a ?? b // c是Int , 2

a是可選項(xiàng)并且a不為nil,b不是可選項(xiàng),所以返回 b

let a: Int? = nil
let b: Int = 2
// 如果不使用??運(yùn)算符
let c: Int
if let tmp = a {
    c = tmp
} else {
    c = b
}

將??轉(zhuǎn)化成代碼判斷就是這樣

七. 多個 ?? 一起使用
let a: Int? = 1
let b: Int? = 2
let c = a ?? b ?? 3
// c是Int 1

let a: Int? = nil
let b: Int? = 2
let c = a ?? b ?? 3
// c是Int 2

let a: Int? = nil
let b: Int? = nil
let c = a ?? b ?? 3
// c是Int  3
以第一組代碼為例分析一下
let a: Int? = 1
let b: Int? = 2
let c = a ?? b ?? 3
// c是Int 1

a是可選項(xiàng)称鳞,b也是可選項(xiàng)涮较,且a不為nil,所以返回的是可選項(xiàng)a冈止,并不是Int類型的a狂票,因?yàn)閎為可選項(xiàng),返回a時a并不會強(qiáng)制解包熙暴,然后就是可選項(xiàng)a和Int3之間進(jìn)行計(jì)算闺属,a是可選項(xiàng)且不為nil,但是“3”不是可選項(xiàng)所以返回的是Int 類型的a
代碼轉(zhuǎn)變過程如下:

let a: Int? = 1
let b: Int? = 2
let c = a ?? b ?? 3
let c = a:int? = 1 : 3
let c =Int 1
// c是Int 1
八. guard語句
guard 條 件 else {
    // do something....
    退出當(dāng)前作用域
    // return周霉、break掂器、continue徒溪、throw error
}
當(dāng)guard語句的條件為false時欢摄,就會執(zhí)行大括號里面的代碼
當(dāng)guard語句的條件為true時,就會跳過guard語句
guard語句特別適合用來“提前退出”
當(dāng)使用guard語句進(jìn)行可選項(xiàng)綁定時播瞳,綁定的常量(let)、變量(var)也能在外層作用域中使用
舉例如下:登錄過程中判斷用戶是否輸入用戶名和密碼
func login(_ info: [String : String]) {
    guard let username = info["username"]
        else {
            print("請輸入用戶名")
            return
    }
    guard let password = info["password"]
        else {
            print("請輸入密碼")
            return
    }
// if username ....
// if password ....
    print("用戶名:\(username)", "密碼:\(password)", "登陸ing")
}
九. 隱式解包(Implicitly Unwrapped Optional)
在某些情況下乃摹,可選項(xiàng)一旦被設(shè)定值之后禁漓,就會一直擁有值
在這種情況下,可以去掉檢查峡懈,也不必每次訪問的時候都進(jìn)行解包璃饱,因?yàn)樗艽_定每次訪問的時候都有值
可以在類型后面加個感嘆號 ! 定義一個隱式解包的可選項(xiàng)
let num1: Int! = 10
let num2: Int = num1
if num1 != nil {
    print(num1 + 6) // 16
}

if let num3 = num1 {
    print(num3)
}

let num1: Int! = nil
// Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value  let num2: Int = num1
十. 字符串插值
可選項(xiàng)在字符串插值或者直接打印時,編譯器會發(fā)出警告
var age: Int? = 10
print("My age is \(age)")
至少有3種方法消除警告
print("My age is \(age!)")
// My age is 10
print("My age is \(String(describing: age))")
// My age is Optional(10)
print("My age is \(age ?? 0)")
// My age is 10

關(guān)于swift的更多知識
請點(diǎn)擊 swift文集!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末肪康,一起剝皮案震驚了整個濱河市荚恶,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌磷支,老刑警劉巖谒撼,帶你破解...
    沈念sama閱讀 217,185評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異雾狈,居然都是意外死亡廓潜,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評論 3 393
  • 文/潘曉璐 我一進(jìn)店門善榛,熙熙樓的掌柜王于貴愁眉苦臉地迎上來辩蛋,“玉大人,你說我怎么就攤上這事移盆〉吭海” “怎么了?”我有些...
    開封第一講書人閱讀 163,524評論 0 353
  • 文/不壞的土叔 我叫張陵咒循,是天一觀的道長据途。 經(jīng)常有香客問我,道長叙甸,這世上最難降的妖魔是什么颖医? 我笑而不...
    開封第一講書人閱讀 58,339評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮裆蒸,結(jié)果婚禮上熔萧,老公的妹妹穿的比我還像新娘。我一直安慰自己光戈,他們只是感情好哪痰,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,387評論 6 391
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著久妆,像睡著了一般晌杰。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上筷弦,一...
    開封第一講書人閱讀 51,287評論 1 301
  • 那天肋演,我揣著相機(jī)與錄音抑诸,去河邊找鬼。 笑死爹殊,一個胖子當(dāng)著我的面吹牛蜕乡,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播梗夸,決...
    沈念sama閱讀 40,130評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼层玲,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了反症?” 一聲冷哼從身側(cè)響起辛块,我...
    開封第一講書人閱讀 38,985評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎铅碍,沒想到半個月后润绵,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,420評論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡胞谈,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,617評論 3 334
  • 正文 我和宋清朗相戀三年尘盼,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片烦绳。...
    茶點(diǎn)故事閱讀 39,779評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡卿捎,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出径密,到底是詐尸還是另有隱情娇澎,我是刑警寧澤,帶...
    沈念sama閱讀 35,477評論 5 345
  • 正文 年R本政府宣布睹晒,位于F島的核電站,受9級特大地震影響括细,放射性物質(zhì)發(fā)生泄漏伪很。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,088評論 3 328
  • 文/蒙蒙 一奋单、第九天 我趴在偏房一處隱蔽的房頂上張望锉试。 院中可真熱鬧,春花似錦览濒、人聲如沸呆盖。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽应又。三九已至,卻和暖如春乏苦,著一層夾襖步出監(jiān)牢的瞬間株扛,已是汗流浹背尤筐。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留洞就,地道東北人盆繁。 一個月前我還...
    沈念sama閱讀 47,876評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像旬蟋,于是被迫代替她去往敵國和親油昂。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,700評論 2 354