Swift 中的解包操作

在 Swift 中我們會接觸到可選類型 Optional,剛開始寫代碼時會被變量后的 ?、!、?? 等符號弄得稀里糊涂。

首先,對于以下代碼:

var num: Int?
num = 10

if num is Optional<Int> {
  print("它是可選類型")
} else {
  print("它是Int類型")
}

在IDE中的if上一定會出現(xiàn)這樣一個warning:'is' test is always true。也就是說 num 不是 Int 類型,而是 Optional 類型。

1. Optional類型

可選類型聲明,如下:

var num : Int?
// let num2 : Int? // let類型變量只可被初始化一次

以上聲明的意思是:聲明了一個變量,它的值可能是一個 Int 值,也可能為 nil 。也即,實際上聲明的是 Optional 類型的變量,而不是聲明了一個 Int 類型的。

正是因為 num 是一個可選類型,所以它才能賦值為 nil ,var num : Int = nil,這樣是不可能賦值成功的,因為Int類型中沒有 nil 這個概念!在 OC 中對象都可以賦值為 nil ,但在 Swift 中能賦值為 nil 的只有 Optional 類型!

2. 關(guān)于解包

解包符號為 !

如果確定一個可選類型的值一定存在,那么我們使用 !進行解包來獲取它的值,或者使用 Optional Binding 來處理。

let possiablestring: String? = "An possiable string"
print(possiablestring!) // 強制解包 確定possiablestring的值確實存在,不需要每次都驗證它的值 let strValues = possiablestring!.hashValue

也可以把 隱式解包可選類型 當成對每次使用的時候自動解包的可選類型。隱式解包不是每次使用的時候 在變量/常量后面加 !,而是直接在定義的時候加 !。

let assumString: String! = "an optional string"
print(assumString, assumString.hashValue)

! 的使用場景:

  1. 強制對 可選選類變量 進行解包;
  2. 聲明 隱式解包的可選類型變量 的時候, 一般用于類中的屬性。

3. 解包的基本思路

使用 if let 或者 guard let,而非強制解包。對于如下方法:

func getHeight(_ height: Float?) -> Float? {
  if height != nil {
    return height! / 100
  }
  return nil
}

以上代碼中使用 ! 對height進行強制解包,然后參與運算,其中每使用一次都要進行強制解包。強制解包過程中一旦解包失敗,就會引起崩潰,安全的解包行為應(yīng)該是通過if let 或者guard let,這種被稱為可選綁定的操作來處理的:

// if let 
func getHeight(_ height: Float?) -> Float? {
    if let unwrapedHeight = height {
    return unwrapedHeight / 100
  }
  return nil
}

//// guard let
//func getHeight(_ height: Float?) -> Float? {
//  guard let unwrapedHeight = height else {
//    return nil
//  }
//  return unwrapedHeight / 100
//}

注意:
對于 if let ,大括號中是符合條件的正常情況,而外部是非正常情況;
對于 guard let ,guard let else中的大括號是異常情況,而外部返回的是正常情況。

多幾個前置 guard let 進行判斷,有時可以讓代碼更具可讀性。

4. 可選鏈的解包

對于以下兩個類:

class Person {
  var phone: Phone?
}

class Phone {
  var number: String?
}

解包時不必一層層進行判斷,因為可選鏈中一旦有某個鏈為 nil ,那么就會返回 nil ,過程如下:

let dora = Person()
  guard let number = dora.phone?.number else {
  return
}

5. _Nonnull、nonnull 與 可選類型 的關(guān)系

對于拼接字符串方法,OC 中是這樣:

- (NSString *)stringByAppendingString:(NSString *)aString;

Swift 中是這樣:

public mutating func append(_ other: String)

僅從 API 來看,OC 的入?yún)⑹呛芪kU的,因為類型是 NSString * ,那么 nil 也可以傳入,這樣會崩掉,應(yīng)該寫成:

- (NSString *)stringByAppendingString:(NSString * _Nonnull)aString;

//// 或
//- (NSString *)stringByAppendingString:(nonnull NSString *)aString;

這樣以便提示程序員,入?yún)⒉荒転榭?。Swift 則不會出現(xiàn)這種情況,other 后面的類型為String ,而不是 String? ,說明入?yún)⑹且粋€非可選類型。

參考文章:
http://www.mamicode.com/info-detail-1160599.html
http://www.itdecent.cn/p/4bfbb0ba4d32

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

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