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

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

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

相信大家在學習和使用Swift的時候,肯定會被 ! 和  ? 搞瘋過, 糾結(jié)這兩個符號到底是個什么鬼 ?鬼知道什么時候使用!,什么時候使用?

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

? 和 ! 到底是個啥

? 和 ! 其實分別是Swift語言中對一種可選類型( Optional) 操作的語法糖。 那可選類型是干什么的呢? Swift中是可以聲明一個沒有初始值的屬性, Swift中引入了可選類型(Optional)來解決這一問題。它的定義是通過在類型生命后加加一個 ? 操作符完成的。

例如: var name: String?

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

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

既然這樣, 那對于 var name: String? 該怎樣去理解這句語法呢?

var name: String?

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

? 和 ! 使用

一旦聲明為Optional的,如果不顯式的賦值就會有個默認值nil。判斷一個Optional的值是否有值,可以用if來判斷:

if name {
    // 有值再操作
}

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

// 例如:

 let length = name?.characters.count 

PS:對于 Optional 值,不能直接進行操作,否則會報錯。

? 的使用場景:

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

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

拆包有兩種方法:

可選綁定(Optional Binding)

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

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

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

硬解包

硬解包即直接在可選類型后面加一個感嘆號(!)來表示它肯定有值。 

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

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

錯誤示范:

var str1:String?  // str1值可能是傳過來的值或者從服務器獲取的值
let msg = "Hi"
let txt = msg + str1! // runtime error

/**
 以上代碼在編譯階段不會報錯.因為使用了硬解包, 編譯器認為可選類型是有值的, 所以編譯是通過的. 當代碼運行起來時, 知名的錯誤將會出現(xiàn): `fatal error: Can't unwrap Optional.None`
*

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

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

舉個很淺顯的栗子:

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

  @IBOutlet weak var headerBGImageView: UIImageView!

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

PS:如果你在隱式解析可選類型沒有值的時候進行取值,會crash。和在沒有值的可選類型里面拆包是一樣的。

! 的使用場景

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

結(jié)束

其實! 和 ? 的問題是很坑的,不要看它僅僅是兩個符號,因為只要有一個不小心,不注意,你會發(fā)現(xiàn)項目運行起來,會莫名的crash掉了,關(guān)鍵是Debug模式也不是很方便定位錯誤類型。 自己整理一下關(guān)于 可選類型的相關(guān)使用,一是記錄和鞏固所學,而是希望會對大家有所幫助。 本文可能會有錯誤和不妥之處,還望提出,我會及時改正。

相關(guān)文章

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

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

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

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

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

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

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

    Swift Json實例詳細解析

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

    iOS Swift讀取本地json文件報錯的解決方法

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

    Swift中的限定擴展詳析

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

    蘋果公司編程語言Swift語言簡介

    這篇文章主要介紹了蘋果公司編程語言Swift語言簡介,Swift 是一門新的編程語言,兼容Objective-C代碼,是用來代替Objective-C的蘋果主力開發(fā)語言,需要的朋友可以參考下
    2014-07-07
  • Swift 3.0基礎(chǔ)學習之擴展

    Swift 3.0基礎(chǔ)學習之擴展

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

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

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

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

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

最新評論