import UIKit
可選類(lèi)型基礎(chǔ)知識(shí)
在swift中nil也是一種數(shù)據(jù)類(lèi)型待牵,只有可選類(lèi)型可以賦值為nil烘苹,其他類(lèi)型都必須進(jìn)行對(duì)應(yīng)類(lèi)型賦值显拳。
所以對(duì)于一些需要進(jìn)行賦值nil的類(lèi)型可以先定義為可選類(lèi)型窿克,然后賦值后調(diào)用的時(shí)候再進(jìn)行可選類(lèi)型的解包調(diào)用
1,可選類(lèi)型定義
- 方式一棕硫,不常用
let name:Optional<String> = nil
- 方式二:語(yǔ)法糖髓涯,其實(shí)是方式一的包裝
var name01:String? = nil
2袒啼,可選類(lèi)型賦值
name01 = optional("z")
name01 = "zhangdanfeng"http://會(huì)自動(dòng)包裝optional
name01 = "jack"
3哈扮,可選類(lèi)型取值
print(name01)//打印結(jié)果是:Optional("jack")
- 需要強(qiáng)制解包(強(qiáng)制解包比較危險(xiǎn)纬纪,如果內(nèi)部沒(méi)有賦值為nil,會(huì)直接崩潰)
print(name01!)//打印結(jié)果是:jack
- 所以標(biāo)準(zhǔn)的解包過(guò)程應(yīng)該先判斷一下是否有值(但是這個(gè)比較麻煩滑肉,所以請(qǐng)看可選綁定)
if name01 != nil {
print(name01!)
print(name01!)
print(name01!)
print(name01!)
}
4包各,可選綁定(可選類(lèi)型每次使用的時(shí)候都需要判斷是有值,然后強(qiáng)制解包靶庙,為了避免這種重復(fù)操作问畅,可以使用可選綁定,如下)
//先判斷name01是否有值六荒,如果有值护姆,解包然后賦值給前面的name01, 如果nil則不執(zhí)行
if let name01 = name01{
print(name01)
}
可選類(lèi)型的應(yīng)用
- 如果url中有中文掏击,url就是空的卵皂;如果按照之前oc的方法就直接把空值傳進(jìn)request中了;
如果在可選類(lèi)型中砚亭,如果為空灯变,那么就不會(huì)強(qiáng)制解包,也不會(huì)調(diào)用request方法
let url: NSURL? = NSURL(string: "http://www.baidu.comd")
if let url = url {
let request = NSURLRequest(url: url as URL)
}
let path: String? = Bundle.main.path(forResource: "zhang.plist", ofType: nil)
可選類(lèi)型的幾種常見(jiàn)應(yīng)用(補(bǔ)充)
- 1捅膘,字符串和數(shù)字之間的直接轉(zhuǎn)換
為什么要轉(zhuǎn)換結(jié)果是可選類(lèi)型:
轉(zhuǎn)換成功那么結(jié)果是字符串添祸,如果轉(zhuǎn)換不成功,那么結(jié)果返回nil寻仗,這樣的話轉(zhuǎn)換結(jié)果就不僅僅是一個(gè)類(lèi)型刃泌,那么只能用泛型,所以選擇了可選類(lèi)型愧沟,然后再轉(zhuǎn)換后進(jìn)行解包即可進(jìn)行安全的使用蔬咬。
(如果結(jié)果只是Int類(lèi)型的話,轉(zhuǎn)換不成功程序就會(huì)直接奔潰)
let str: String = "123"
let num: Int? = Int(str)//用可選類(lèi)型可以在取值不成功的時(shí)候賦值為空沐寺,而不是直接報(bào)錯(cuò)崩潰
//因而可以賦值為可選類(lèi)型林艘,通過(guò)可選綁定對(duì)可選類(lèi)型進(jìn)行解包
if let num = num {
print(num)
}
- 2,根據(jù)文件名取文件路徑
let path: String? = Bundle.main.path(forResource: "zhang.plist", ofType: nil)
path//當(dāng)然左邊也可以賦值為字符串混坞,那么右邊就需要強(qiáng)制解包狐援,如果為空,直接崩潰
if let path = path {
print(path)
}
- 3究孕, 字符串轉(zhuǎn)成url
let url = URL(string: "http://wwwzhang在.baidu.com")
if let url = url {
print(url)
}
4啥酱,從字典中取出元素
any類(lèi)型和any的可選類(lèi)型是兩種類(lèi)型,如果根據(jù)鍵取可能取到值厨诸,也可能取不到值镶殷,所以從字典或者字符串中取得的值的類(lèi)型是any的可選類(lèi)型,需要進(jìn)行解包后才是any類(lèi)型*
let dict:[String : Any] = ["name":"zhang","age":20,"num":200]
let namezzz: Any? = dict["dd"]
print(namezzz ?? "取值錯(cuò)誤微酬,可能是鍵值不對(duì)")
if let namezzz = namezzz {
print(namezzz)
}
類(lèi)型轉(zhuǎn)換
as ? 轉(zhuǎn)換成可選類(lèi)型绘趋,所以如果結(jié)果沒(méi)有會(huì)直接返回為nil颤陶,不會(huì)崩潰
as ! 轉(zhuǎn)換成具體類(lèi)型,所以如果結(jié)果會(huì)直接崩潰
let str01 = "www.baidu.com"
(str01 as NSString).substring(to: 6)
- 1陷遮,as ?:轉(zhuǎn)換成一個(gè)可選類(lèi)型滓走,系統(tǒng)判斷之后,如果可以轉(zhuǎn)化成功帽馋,則轉(zhuǎn)化可選類(lèi)型搅方,轉(zhuǎn)化不成功則返回nil
let name01 = dict["name"] as? String//as ?在轉(zhuǎn)化失敗的時(shí)候會(huì)返回nil,而如果用as !绽族,那么直接崩潰哦
if let name01 = name01 {
print(name01)
}
//上面代碼簡(jiǎn)化:
if let name01 = dict["name"] as? String{
print(name01)
}
//這一步和直接不適用as ?的區(qū)別在于:有時(shí)候不能確定name對(duì)應(yīng)的值是字符串的時(shí)候可以先轉(zhuǎn)化一下姨涡,如果已經(jīng)知道肯定是字符串,則可以直接不用as ?
- 2吧慢,as !:轉(zhuǎn)換成一個(gè)具體類(lèi)型绣溜,系統(tǒng)判斷之后,如果可以轉(zhuǎn)化成功娄蔼,則轉(zhuǎn)化可選類(lèi)型怖喻,轉(zhuǎn)化不成功則崩潰
let name02 = dict["name"] as! String//as ?在轉(zhuǎn)化失敗的時(shí)候會(huì)返回nil,而如果用as !岁诉,那么直接崩潰哦
print(name02)