[Swift] iOS開發筆記(四):Optional Types

摘要:[Swift] Optional Types

在參考Swift一些Sample Code的時候,常常看到一些帶有 驚嘆號(!)還有(?)在一些宣告中,翻了一下Swift的文件,這篇來討論一下這個Swift的Optionals type。怎麼簡單的一句話解釋Optionals Type呢?引用一篇網路文獻中提到的一句話:

An optional in Swift is a variable that can hold either a value or no value.

 

在Swift Programming Language電子書的The Basics章節提到:

Swift also introduces optional types, which handle the absence of a value. Optionals say either “there is a value, and it equals x” or “there isn’t a value at all”. Optionals are similar to using nil with pointers in Objective-C, but they work for any type, not just classes. Optionals are safer and more expressive than nil pointers in Objective-C and are at the heart of many of Swift’s most powerful features.

Optionals are an example of the fact that Swift is a type safe language. Swift helps you to be clear about the types of values your code can work with. If part of your code expects a String, type safety prevents you from passing it an Int by mistake. This enables you to catch and fix errors as early as possible in the development process.

 

上述的簡單結論可以這樣看,?屬於Optional types。他負責處理當指定的變數沒有被指定值的時候,會塞一個nil直給這個變數宣告。

optional 有點像在 Objective-C 中使用nil,但是它可以用在任何型別上,不僅僅是類別。

nil表示「缺少一個合法的物件(Instance)」,並且nil不能用於非 optional type的常數和變數。

Swift 的nil和 Objective-C 中的nil並不一樣。在 Objective-C 中,nil是一個指向不存在物件的指標。在 Swift 中,nil不是指標——它是一個確定的值,用來表示值不存在。任何型別的 optional 狀態都可以被設置為nil,不只是物件型別。

當你確定 optional 確實包含值之後,你可以在 optional 的名字後面加一個感嘆號(!)來獲取值。這個驚嘆號表示「我知道這個 optional 有值,請使用它。」這被稱為 optional 值的強制解析

 

 

1. 宣告使用者變數

先建立一個基礎簡單的範例,設定一個使用者名稱Ben,並指定初始值,然後用println方法把它印出來。

 

程式:

import Foundation

var username: String = "Ben"

println("Hello, \(username)")

 

執行結果:

 

2. 未指派初始值給變數

如果修正程式為底下範例,去設定宣告一個變數,在沒有輸入任何值時,我們又使用到這個值,這時候就會在開發階段就有錯誤通知。在使用username必須要初始化username。

 

程式:

var username: String

println("Hello, \(username)")

 

執行結果:

 

3. 宣告變數為Optionals 型別

同樣的範例,在String後面加入了一個問號?,用來指定這個變數為optional chaining。

這樣當他沒有被賦予初始值的時候,會被塞入一個nil給這個變數。

 

程式:

var username: String?

println("Hello, \(username)")

 

執行結果:

var username: String?

println("Hello, \(username)")

 

4. 可以手動指定nilOptionals 型別變數

當我在一個變數宣告的後面帶入了一個問號(?),即為宣告這個變數為Optional type型別。以下方的範例來看,在宣告一個String型別的變數過程中,在String型別後面帶了一個?

,這時可以指定字串給test變數,也可以指定nil給這個變數。

 

程式:

var test: String? = "Hello World"

test = nil

println(test)

 

如果去除掉這個問號 (?),這時在指定nil給test變數的時候,就會提示你語法上錯誤,

無法指定nil給String型別的變數test。

 

執行結果:

 

在Objective-C裡面去呼叫一個物件,如果這個物件沒有(Instance)實例存在時,Objective-C會回傳NSNotFound來通知這個值不存在。所以我們要做一些延伸的程式撰寫,就可以利用到這個NSNotFound來協助我們判斷。

 

5. 帶入驚嘆號! 的強制解析

這個範例有兩個類別,分別是Class Person與 Class Residence。接著建立Persion的Instance。而在Persion的residence property 預設是 initialized 成nil值。

這時以下方的範例,嘗試以 ! 來強制解析取得 numberOfRooms時,會在runtime階段產生例外的錯誤狀況。因為這裡沒有residence value可以被解析。

 

程式:

class Person{
    var residence: Residence?
}


class Residence {
    var numberOfRooms = 1
}

let john = Person()
println(john.residence!.numberOfRooms)

 

執行結果:

 

 

class Person{
    var residence: Residence?
}

class Residence {
    var numberOfRooms = 1
}

let john = Person()
john.residence = Residence()
println(john.residence!.numberOfRooms)

 

執行結果:

 

 

參考資料:

Optional Chaining

https://developer.apple.com/library/prerelease/mac/documentation/Swift/Conceptual/Swift_Programming_Language/OptionalChaining.html

The Swift Programming Language

https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/TheBasics.html

基礎部分

http://tommy60703.gitbooks.io/swift-language-traditional-chinese/chapter2/01_The_Basics.html