Swift語言指南(六)--可選值

來源:互聯網
上載者:User

在值可能不存在的情況下使用可選值(optional), 可選值是:

  · 存在一個值,這個值等於 x

  · 不存在任何值

 註:

在 C 和 Objective-C 中可選值的概念並不存在。Objective-C 中(與可選值)最相近的(概念)是,一個以對象為傳回值的方法,也可以返回 nil,nil表示“不存在有效對象”。不過,這規則只對對象有效——對於結構、基本的 C 類型或枚舉值無效。對於這些類型,Objective-C 語言的方法通常會返回一個特殊值(如 NSNotFound)來表示值不存在。這種策略假定該方法的調用方知道要測試傳回值是否等於某個特殊值,並且記得要作此檢查。Swift 的可選值允許表示任何類型不存在值,無需定義特殊常量。

這裡有個例子。Swift 的 String 類型有一個名為 toInt 的方法,可嘗試將 String 值轉為 Int 值。然而,不是所有字串都可以轉換為整數。字串 “123”可以轉換為數值 123,而字串 “hello, world” 顯然沒有對應的數值。

下面的例子會嘗試用 toInt 方法將 String 轉換為 Int

1 let possibleNumber(可能是數字) = "123"2 let convertedNumber(轉換得到的數字) = possibleNumber.toInt() 
3 //convertedNumber被推斷為 "Int?" 類型,或 "可選的 Int"

因為 toInt 方法可能會轉換失敗,因此它返回的是一個 可選的 Int 型,而不是 Int 型。可選的 Int寫法為 Int?,而不是 Int。問號表明示該類型包含的值是可選的,即 Int? 可能包含某個 Int 類型的值,也可能不含任何值。(它不能包含其他類型的值,如 Bool 值或 String 值,它要麼是 Int 要麼就不存在。)

 

if 語句與強制拆包

可使用 if 語句測試可選值是否含有值。如果有,則求值結果返回 true,否則返回 false

一旦確認可選值的確含有一個值,就可以通過在可選值變數名的末尾添加驚嘆號(!)來訪問其內部的值。驚嘆號明確表達:“我知道這個可選值確實存在值,請使用它(那個值)吧!”這種操作名為對可選值進行強制拆包force-unwrap):

關於 if 語句的更多資訊,請見 流程式控制制。

 

註:

嘗試用 ! 訪問不存在的可選值時會在運行時報錯,在用 ! 強行拆包之前,務必確保可選值確實包含一個非 nil 的值。

 

可選值綁定

可以使用可選值綁定optional binding)測試可選值是否包含一個值,如果有,則將該值以臨時常量或變數的形式拆包備用。可選值綁定可以與 if 或 while 語句結合使用,這樣只需要一步就可以檢查是否存在值、提取該值、並存放到常量或變數中。關於 if 與 while 語句的更多資訊在 流程式控制制 一章中有講過。

可選值綁定與 if 混用可以是這樣:

1 if let constantName = someOptional {2     statements3 }

 

上文中的 possibleNumber 一例,可以用可選值綁定代替強制拆包:

1 if let actualNumber = possibleNumber.toInt() {2      println("\(possibleNumber) 的整數值為 \(actualNumber)") 3 } else {  4      println("\(possibleNumber) 無法轉換為整數") 5 } 6  // 輸出 "123 的整數值為 123"

可以這樣理解:

“如果 possibleNumber.toInt() 返回的 可選的 Int 包含一個值,則建立一個名為 actualNumber 的常量,並將常量的值設為可選值中包含的值。”

如果轉換成功,常量 actualNumber 將可供 if 語句的第一個分支語句使用。該常量已經被可選值包含的值初始化,因此不再需要用尾碼 ! 訪問其值。本例中,actualNumber 被直接用來輸出轉換結果。

常量與變數均可用於可選值綁定。如果需要在第一個分支中處理 actualNumber 的值,可以改寫為 if var actualNumber,這樣可選值的值將作為變數而非常量拆包。

 

nil

要將可選變數設為空白值(沒有值或值不存在的狀態,valueless),可以給它賦特殊值 nil

1 var serverResponseCode(伺服器狀態代碼): Int? = 4042 //伺服器狀態代碼包含一個實際存在的 Int 值:404 
3 serverResponseCode= nil
4 // 伺服器狀態代碼 現在不含任何值

 

註:

nil 不能用於非可選值的常量或變數。如果代碼中的常量或變數需要適配值不存在的某種特殊情況,務必將它聲明為適用的可選實值型別

如果你所定義的可選值未提供預設值,該常量或變數將被自動設為 nil

1 var surveyAnswer: String?2 // surveyAnswer 被自動設為 nil

 

註:

Swift 的 nil 與 Objective-C 的 nil 不同。Objective-C 的 nil 是指向一個不存在對象的指標,而 Swift 的 nil 不是指標——它是一種表示值不存在的特殊類型。任何類型的可選值都能賦值為nil,不僅限於物件類型。

 

可選值的隱式拆包

如上所述,可選值指允許“值不存在”的常量或變數。可以通過 if 語句測試可選值是否存在值,也可以通過可選值綁定按條件拆包,並在該可選值的值存在的情況下才訪問它的值。

有時根據程式結構可以知曉一個可選值在首次賦值後,必然存在值。這時,可以不必每次訪問時都檢測並提取該可選值的值,因為可以安全地假設它那時一定存在值。

這些可選值可定義為隱式拆包的可選值(implicitly unwrapped optional)。你可以通過在希望標為可選的類型名稱後面,用驚嘆號 (String!) 代替問號 (String?)的方式書寫隱式拆包可選值

隱式拆包的可選值在可選值首次定義後即確認存在值,在此之後任何時刻都能被明確地(肯定有值)使用。Swift 中隱式拆包可選值主要應用於類初始化,詳見 外部參考與隱式拆包的可選屬性(待譯)。

隱式拆包的可選值在運行環境裡就是普通的可選值,但能夠像非可選值那樣使用,無需在每次訪問時拆包。下例顯示了 可選的 String 與 隱式拆包的可選 String 之間的行為差異:

1 let possibleString(可能的字串): String? = "An optional String。(一個可選的String)"2 println(possibleString!) // 訪問其值時需要添加驚嘆號3 // 輸出 "可選的 String。"4 let assumedString(假設的字串): String! = "An implicitly unwraped optional String。(隱式的拆包的可選Stirng)" 
5 println(assumedString) // 訪問其值時無需驚嘆號
6 // 輸出 "隱式拆包的可選 String。"

 

可以認為,隱式拆包的可選值即授予可選值在被使用時自動拆包的許可權(即無需再次手動進行拆包)。不必每次使用可選值時都在名稱後面添加驚嘆號,只需在聲明時在可選實值型別後面加上驚嘆號即可。

 

註:如果在隱式拆包的可選值存在值之前就嘗試訪問(不存在值時不可進行隱式拆包),運行時會報錯。結果與在普通可選值尚未賦值時直接加驚嘆號就引用相同。

隱式拆包的可選值也可以當作像普通可選值那樣,檢查是否存在值:

1 if assumedString {2     println(assumedString)3 }4 // 輸出 "An implicitly unwraped optional String。(隱式的拆包的可選Stirng)"

 

隱式拆包的可選值同樣可以使用可選值綁定,單條陳述式完成檢查值並拆包:

1 if let definiteString(肯定是字串) = assumedString(假定是字串) { 2    println(definiteString)  3  } 4 // 輸出 "隱式拆包的可選 String。"

 

 

註:

當變數在後續過程中可能變為 nil 時,不應使用隱式拆包的可選值。如果在變數聲明周期內都需要檢查 nil 值,請務必使用普通的可選類型量。

 

謝謝,Swifter-QQ群:362232993,同好者進~ 

Fork:https://github.com/Joejo/Swift-lesson-for-chinese

 

 

 

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.