欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Swift中 !和 ?的區(qū)別及使用

 更新時(shí)間:2016年12月17日 17:53:58   投稿:hebedich  
這篇文章主要介紹了Swift中 !和 ?的區(qū)別及使用的相關(guān)資料,需要的朋友可以參考下

相信大家在學(xué)習(xí)和使用Swift的時(shí)候,肯定會(huì)被 ! 和  ? 搞瘋過(guò), 糾結(jié)這兩個(gè)符號(hào)到底是個(gè)什么鬼 ?鬼知道什么時(shí)候使用!,什么時(shí)候使用?

下面就說(shuō)一下! 和 ? 區(qū)別以及該怎么使用!

? 和 ! 到底是個(gè)啥

? 和 ! 其實(shí)分別是Swift語(yǔ)言中對(duì)一種可選類型( Optional) 操作的語(yǔ)法糖。 那可選類型是干什么的呢? Swift中是可以聲明一個(gè)沒(méi)有初始值的屬性, Swift中引入了可選類型(Optional)來(lái)解決這一問(wèn)題。它的定義是通過(guò)在類型生命后加加一個(gè) ? 操作符完成的。

例如: var name: String?

Optional其實(shí)是個(gè)enum,里面有None和Some兩種類型。其實(shí)所謂的nil就是Optional.None , 非nil就是Optional.Some, 然后會(huì)通過(guò)Some(T)包裝(wrap)原始值,這也是為什么在使用Optional的時(shí)候要拆包(從enum里取出來(lái)原始值)的原因。

這里是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 
}

既然這樣, 那對(duì)于 var name: String? 該怎樣去理解這句語(yǔ)法呢?

var name: String?

//  上面這個(gè)Optional的聲明,是”我聲明了一個(gè)Optional類型值,它可能包含一個(gè)String值,也可能什么都不包含”,也就是說(shuō)實(shí)際上我們聲明的是Optional類型,而不是聲明了一個(gè)String類型 。

? 和 ! 使用

一旦聲明為Optional的,如果不顯式的賦值就會(huì)有個(gè)默認(rèn)值nil。判斷一個(gè)Optional的值是否有值,可以用if來(lái)判斷:

if name {
    // 有值再操作
}

怎么使用Optional值呢?文檔中也有提到說(shuō),在使用Optional值的時(shí)候需要在具體的操作,比如調(diào)用方法、屬性、下標(biāo)索引等前面需要加上一個(gè)?,如果是nil值,也就是Optional.None,會(huì)跳過(guò)后面的操作不執(zhí)行,如果有值,就是Optional.Some,可能就會(huì)拆包(unwrap),然后對(duì)拆包后的值執(zhí)行后面的操作,來(lái)保證執(zhí)行這個(gè)操作的安全性。

// 例如:

 let length = name?.characters.count 

PS:對(duì)于 Optional 值,不能直接進(jìn)行操作,否則會(huì)報(bào)錯(cuò)。

? 的使用場(chǎng)景:

1.聲明Optional值變量
2.用在對(duì)Optional值操作中,用來(lái)判斷是否能響應(yīng)后面的操作
3.使用 as? 向下轉(zhuǎn)型(Downcast)

上面提到Optional值需要拆包(unwrap)后才能得到原來(lái)值,然后才能對(duì)其操作,那怎么來(lái)拆包呢?

拆包有兩種方法:

可選綁定(Optional Binding)

可選綁定(Optional Binding)是一種更簡(jiǎn)單更推薦的方法來(lái)解包一個(gè)可選類型。 使用可選綁定來(lái)檢查可選類型的變量有值還是沒(méi)值。如果有值, 解包它并且將值傳遞給一個(gè)常量或者變量。

// 例子最為簡(jiǎn)單明了
var str: String? = "Hello"
let greeting = "World!"
if let name = str {
  let message = greeting + name
  print(message)
}

/**
自然語(yǔ)言解釋意思:就是如果str有值,解包它,并且將它的值賦值給name, 然后執(zhí)行下面的條件語(yǔ)句; 如果str為空, 直接跳過(guò)條件語(yǔ)句塊。
*/ 

硬解包

硬解包即直接在可選類型后面加一個(gè)感嘆號(hào)(!)來(lái)表示它肯定有值。 

 
var str1: String? = "Hello"
let greeting = "World!"
if (str1 != nil) {
  let message = greeting + str1!
  print(message)
}

/**
上面例子,我們只是自己知道str1肯定有值, 所以才直接硬解包了str1變量。 但是萬(wàn)一有時(shí)候我們的感覺(jué)是錯(cuò)的, 那程序在運(yùn)行時(shí)可能會(huì)出現(xiàn)嚴(yán)重的錯(cuò)誤. 所以Swift中是推薦先檢查可選類型是否有值, 然后再進(jìn)行解包的!
*/ 

錯(cuò)誤示范:

var str1:String?  // str1值可能是傳過(guò)來(lái)的值或者從服務(wù)器獲取的值
let msg = "Hi"
let txt = msg + str1! // runtime error

/**
 以上代碼在編譯階段不會(huì)報(bào)錯(cuò).因?yàn)槭褂昧擞步獍? 編譯器認(rèn)為可選類型是有值的, 所以編譯是通過(guò)的. 當(dāng)代碼運(yùn)行起來(lái)時(shí), 知名的錯(cuò)誤將會(huì)出現(xiàn): `fatal error: Can't unwrap Optional.None`
*

PS:對(duì)于  ! 操作符,這里的變量值一定是非nil的!

其實(shí), 還有一種叫隱式拆包(Implicitly Unwrapped Optionals),比如 對(duì)于會(huì)在viewDidLoad進(jìn)行初始化的變量,可以直接定義為var str :String! 等于說(shuō)你每次對(duì)這種類型的值操作時(shí),都會(huì)自動(dòng)在操作前補(bǔ)上一個(gè)!進(jìn)行拆包,然后在執(zhí)行后面的操作,當(dāng)然如果該值是nil,會(huì)報(bào)錯(cuò)crash掉。

舉個(gè)很淺顯的栗子:

// 在一個(gè)viewController里面,從xib里面拖一個(gè)UIImageView控件, 你會(huì)發(fā)現(xiàn)Xcode會(huì)自動(dòng)給你轉(zhuǎn)成下面的形式

  @IBOutlet weak var headerBGImageView: UIImageView!

/**
 聲明Implicitly Unwrapped Optionals值,一般用于類中的屬性
*/

PS:如果你在隱式解析可選類型沒(méi)有值的時(shí)候進(jìn)行取值,會(huì)crash。和在沒(méi)有值的可選類型里面拆包是一樣的。

! 的使用場(chǎng)景

1.強(qiáng)制對(duì)Optional值進(jìn)行拆包(unwrap)
2.聲明隱式拆包變量,一般用于類中的屬性

結(jié)束

其實(shí)! 和 ? 的問(wèn)題是很坑的,不要看它僅僅是兩個(gè)符號(hào),因?yàn)橹灰幸粋€(gè)不小心,不注意,你會(huì)發(fā)現(xiàn)項(xiàng)目運(yùn)行起來(lái),會(huì)莫名的crash掉了,關(guān)鍵是Debug模式也不是很方便定位錯(cuò)誤類型。 自己整理一下關(guān)于 可選類型的相關(guān)使用,一是記錄和鞏固所學(xué),而是希望會(huì)對(duì)大家有所幫助。 本文可能會(huì)有錯(cuò)誤和不妥之處,還望提出,我會(huì)及時(shí)改正。

相關(guān)文章

  • 深入講解Swift的內(nèi)存管理

    深入講解Swift的內(nèi)存管理

    不管在什么語(yǔ)言里,內(nèi)存管理的內(nèi)容都很重要,Swift使用自動(dòng)引用計(jì)數(shù)來(lái)管理應(yīng)用程序的內(nèi)存使用。這表示內(nèi)存管理已經(jīng)是Swift的一部分,在大多數(shù)情況下,你并不需要考慮內(nèi)存的管理。本文主要介紹了Swift中內(nèi)存管理的相關(guān)資料,需要的朋友可以參考。
    2017-03-03
  • Swift解決UITableView空數(shù)據(jù)視圖問(wèn)題的簡(jiǎn)單方法

    Swift解決UITableView空數(shù)據(jù)視圖問(wèn)題的簡(jiǎn)單方法

    這篇文章主要給大家介紹了關(guān)于Swift解決UITableView空數(shù)據(jù)視圖問(wèn)題的簡(jiǎn)單方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用swift具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2018-10-10
  • 在Swift中使用Objective-C編寫類、繼承Objective-C類

    在Swift中使用Objective-C編寫類、繼承Objective-C類

    這篇文章主要介紹了在Swift中使用Objective-C編寫類、繼承Objective-C類等操作方法介紹,需要的朋友可以參考下
    2014-07-07
  • Swift Json實(shí)例詳細(xì)解析

    Swift Json實(shí)例詳細(xì)解析

    這篇文章主要給大家介紹了關(guān)于Swift Json解析的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考借鑒,下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。
    2018-03-03
  • iOS Swift讀取本地json文件報(bào)錯(cuò)的解決方法

    iOS Swift讀取本地json文件報(bào)錯(cuò)的解決方法

    只要是app開發(fā)者都知道,從服務(wù)器端獲得的數(shù)據(jù)要不就是json格式的數(shù)據(jù),要么就是xml格式的數(shù)據(jù),而這篇文章主要給大家介紹了關(guān)于iOS Swift讀取本地json文件報(bào)錯(cuò)的解決方法,需要的朋友可以參考借鑒,下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-11-11
  • Swift中的限定擴(kuò)展詳析

    Swift中的限定擴(kuò)展詳析

    擴(kuò)展就是向一個(gè)已有的類、結(jié)構(gòu)體或枚舉類型添加新功能。下面這篇文章主要給大家介紹了關(guān)于Swift中限定擴(kuò)展的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起看看吧。
    2018-03-03
  • 蘋果公司編程語(yǔ)言Swift語(yǔ)言簡(jiǎn)介

    蘋果公司編程語(yǔ)言Swift語(yǔ)言簡(jiǎn)介

    這篇文章主要介紹了蘋果公司編程語(yǔ)言Swift語(yǔ)言簡(jiǎn)介,Swift 是一門新的編程語(yǔ)言,兼容Objective-C代碼,是用來(lái)代替Objective-C的蘋果主力開發(fā)語(yǔ)言,需要的朋友可以參考下
    2014-07-07
  • Swift 3.0基礎(chǔ)學(xué)習(xí)之?dāng)U展

    Swift 3.0基礎(chǔ)學(xué)習(xí)之?dāng)U展

    擴(kuò)展是向一個(gè)已有的類、結(jié)構(gòu)體或枚舉類型添加新的功能(在swift中擴(kuò)展沒(méi)有名字)。相當(dāng)于Objective-C中Category(OC中可以有名字的,而且只能擴(kuò)展類)。這篇文章主要介紹了Swift 3.0基礎(chǔ)學(xué)習(xí)之?dāng)U展的相關(guān)資料,需要的朋友可以參考下。
    2017-03-03
  • Swift如何為網(wǎng)頁(yè)承載頁(yè)面添加更多功能詳解

    Swift如何為網(wǎng)頁(yè)承載頁(yè)面添加更多功能詳解

    這篇文章主要給大家介紹了關(guān)于Swift如何為網(wǎng)頁(yè)承載頁(yè)面添加更多功能的相關(guān)資料,包括添加菊花加載的效果、添加跳轉(zhuǎn)到Safari的功能、添加復(fù)制鏈接的功能以及添加分享網(wǎng)頁(yè)的功能,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2018-05-05
  • SwiftUI 中創(chuàng)建反彈動(dòng)畫的實(shí)現(xiàn)

    SwiftUI 中創(chuàng)建反彈動(dòng)畫的實(shí)現(xiàn)

    這篇文章主要介紹了SwiftUI 中創(chuàng)建反彈動(dòng)畫的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-10-10

最新評(píng)論