swift語言之(可選類型?和隱式可選類型!)

可選類型、隱式可選類型

在swift中,可選類型其根源是一個(gè)枚舉型,里面有None和Some兩種類型。其實(shí)所謂的nil就是Optional.None, 非nil就是Optional.Some, 然后會(huì)通過Some(T)包裝(wrap)原始值,這里是enum Optional的定義:

enum Optional<T> : LogicValue, Reflectable {  
    case None  
    case Some(T)  
    init()  
    init(_ some: T)  
  
    /// Allow use in a Boolean context.  
    func getLogicValue() -> Bool  
  
    /// Haskell's fmap, which was mis-named  
    func map<U>(f: (T) -> U) -> U?  
    func getMirror() -> Mirror  
}  

語法使用“?”操作符及"!"號(hào)操作符

如:“var optionalString: String? = "Hello"
optionalString == nil
 
var optionalName: String? = "John Appleseed"
var greeting = "Hello!"
if let name = optionalName {
    greeting = "Hello, \(name)"
}”

大家把optionalName改為nil時(shí)看一下會(huì)有什么結(jié)果?按照理解,應(yīng)該是? = 后的為可選值,即當(dāng)我們的的變量為nil時(shí),這里如果有?=操作,則會(huì)使用?=后的值作為默認(rèn)值,而不會(huì)為nil. 這個(gè)等有環(huán)境時(shí),驗(yàn)證一下。
經(jīng)驗(yàn)證:
分別執(zhí)行:

var optional :String? = "ok good";//注意?與=號(hào)之間有空格?號(hào)緊貼最后一個(gè)字母不能有空格  
println(optional) 

輸出為:
ok good

var optional :String?//注意?與=號(hào)之間有空格?號(hào)緊貼最后一個(gè)字母不能有空格  
println(optional)  

輸出為:
nil

來看下官方釋為隱式解包:主要用在一個(gè)變量/常量在定義瞬間完成之后值一定會(huì)存在的情況。這主要用在類的初始化過程中。

var optionVariables:String? //?相當(dāng)于下面這種寫法的語法糖  
//var optionVariables : Optional<Int>  
let value = optionVariables?.hashValue  
/* 
optionVariables是可選類型的字符串,如果optionVariables是nil,則hashValue也為nil 
如果optionVariables不為nil,hashValue就是strValue字符串的哈希值 
到這里我們看到了?的兩種使用場(chǎng)景: 
1.聲明Optional值變量 
2.用在對(duì)Optional值操作中,用來判斷是否能響應(yīng)后面的操作 
*/  
  
//對(duì)于可選類型變量,不能直接進(jìn)行操作,否則會(huì)報(bào)錯(cuò)  
//let hashval = optionVariables.hashValue //'String?' does not have a member named 'hashValue'  
//因此要訪問值就需要解包,解包有兩種  
//第一種:使用if let/var xxx =   
if let hv = optionVariables  
{  
    //run ok;  
}  
  
//第二種:使用!號(hào)  
let hv = optionVariables!.hashValue  
  
//這里的!表示“我確定這里的的strValue一定是非nil的,盡情調(diào)用吧” ,比如這種情況:  
  
if optionVariables {  
    let hashv = optionVariables!.hashValue  
}  
//{}里的optionVariables一定是非nil的,所以就能直接加上!,強(qiáng)制拆包(unwrap)并執(zhí)行后面的操作  

凡在變量或常量后加上?的都是一個(gè)可選變量/可選常量
凡在變量或常量后加上!的都是隱式可選變量/常量,有點(diǎn)難理解,首先該變量或常量滿足可選類型,其主要是可被當(dāng)生一般的變量/常量來使用,而不需要每次都驗(yàn)證是否有值。
注:如果一個(gè)隱式解包的可選類型不包含一個(gè)實(shí)際值,那么對(duì)它的訪問會(huì)拋出一個(gè)運(yùn)行時(shí)錯(cuò)誤。在變量/常量名后面加!的情況也是一樣的。

var possibleString: String? = "An optional string."  
//possibleString = nil  
println(possibleString) // possibleString 為可選變量,需要使用!來訪問的值  

分析:首先 possibleString 因后面帶上了?說明這是一個(gè)可選的,同時(shí)前面加上var為變量,所以這是一個(gè)可選類型的變量。其可選值為 "An optional string." 再來看執(zhí)行println后,可以看出輸出為 An optional string. 這點(diǎn)很明顯。再來看一下把println這句改一下改為 (即在可選變量后面加上一個(gè)!號(hào)。)

println(possibleString!) // possibleString 為可選變量,需要使用!來訪問的值

這里結(jié)果與沒有加!號(hào)時(shí)是完全一樣的,輸出為An optional string.
好,現(xiàn)在重點(diǎn)來了,這是很關(guān)鍵的一個(gè)測(cè)試。把possibleString = nil 這句注釋放開讓其動(dòng)行,再分別來看一下println帶!和不帶!的情況:
情況一:不帶!號(hào)時(shí),輸出為nil .

  var possibleString: String? = "An optional string."  
        possibleString = nil  
        println(possibleString)  

情況二:再來看一下帶!號(hào)

  var possibleString: String? = "An optional string."  
        possibleString = nil  
        println(possibleString!) // possibleString 為可選變量,需要使用!來訪問的值

這時(shí)運(yùn)行到這句println就會(huì)crash了。會(huì)報(bào)
fatal error: Can't unwrap Optional.None
錯(cuò)誤。
在情況一時(shí),為什么不會(huì)報(bào)錯(cuò),是因?yàn)檫@是一個(gè)可選變量當(dāng)變量為nil時(shí),自動(dòng)驗(yàn)證是否有可選的值,有則使用可選值,在情況二,加上!訪問符來訪問possibleString 變量,但由于possibleString設(shè)為了nil (等價(jià)于var possibleString: String?) 其并沒有包含一個(gè)實(shí)際值,所以拋異常.同樣對(duì)于下面使用!號(hào)來聲明的也一樣

var assumedString: String! = "An implicitly unwrapped optional string."  
        assumedString = nil  
        println(assumedString!)

如果你定義了一個(gè)可選類型并且沒有給予初始值的時(shí)候,會(huì)默認(rèn)設(shè)置為nil
var surveyAnswer: String? // 初自動(dòng)設(shè)置為nil
注: Swift 的nil不同于Object-C中的nil. Object-C中,nil是一個(gè)指針指向不存在的對(duì)象。Swift中,nil不是指針而是一個(gè)特定類型的空值。任何類型的可選變量都可以被設(shè)為nil,不光是指針。
在swift中作何變量/常量的聲明都必須帶有初始值,否則就要聲明為可選型。
即var btn:UIButton 這樣是編譯報(bào)錯(cuò)的。因些必須改為帶初始化的如:
var btn2 :UIButton = UIButton()
或者使用? 和! 來約束。
因此常常聲明可選或隱式可選變量如:
var btn :UIButton? // 默認(rèn)btn = nil
var edt :UITextField! // 默認(rèn)edt = nil

最后編輯于
?著作權(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)容

  • SwiftDay011.MySwiftimport UIKitprintln("Hello Swift!")var...
    smile麗語閱讀 4,098評(píng)論 0 6
  • 關(guān)于 Swift 重要這個(gè)文檔所包含的準(zhǔn)備信息, 是關(guān)于開發(fā)的 API 和技術(shù)的。這個(gè)信息可能會(huì)改變, 根據(jù)這個(gè)文...
    無灃閱讀 4,624評(píng)論 1 27
  • 2014年的蘋果全球開發(fā)者大會(huì)(WWDC),當(dāng)Craig Federighi向全世界宣布“We have new ...
    yeshenlong520閱讀 2,402評(píng)論 0 9
  • Swift 是一門開發(fā) iOS, macOS, watchOS 和 tvOS 應(yīng)用的新語言。然而,如果你有 C 或...
    XLsn0w閱讀 988評(píng)論 2 1
  • Swift 介紹 簡(jiǎn)介 Swift 語言由蘋果公司在 2014 年推出,用來撰寫 OS X 和 iOS 應(yīng)用程序 ...
    大L君閱讀 3,428評(píng)論 3 25

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