1. 程式人生 > 實用技巧 >Swift中的Optional型別

Swift中的Optional型別

Swift當中的Optional型別,表明一個變數可能有確認的值,也可能不包含任何值。不包含任何值在Swift當中,就是一個nil。

Swift當中的變數或者常量,在使用之前必須得賦值,但是對於Optional型別來說,情形有點不一樣。對於Optional變數來說,使用之前可以不用賦值:

var a: Int?
var b = a //正確
let c = a //正確

這是因為對於Optional變數來說,如果不賦任何值,編譯器預設賦nil。

但是上述情況對於Optional常量不適用,如果Optional常量未顯示賦值就是用,編譯器報錯:

let c: Int?
var a = c //報錯

即使顯示對Optional常量賦值nil,也是可以的:

let c: Int?
c = nil
var a = c //正確

Swift當中不能重複宣告變數,即使變數名字相同,型別不同也不行,或者將同一個名字宣告為變數的同時,還宣告成常量也不行。在這裡,將相同名字的變數宣告成Optional型別也不行:

var a:Int
var a:Int? //報錯

let a:Int
var a:Int? //報錯

let a:Int
let a:Int? //報錯

總結起來就是一句話,如果變數或者常量相同,那麼就只能宣告一次。

Swift中Optional的變數或者常量,不能直接複製給非Optional的變數或者常量,但是反過將非Optional的變數或者常量,賦值給Optional的變數或者常量是沒問題的:

let a: Int? = 1
let b: Int = a //報錯


var a: Int? = 1
var b: Int = a //報錯

let a: Int = 1
let b: Int? = a //可以

var a: Int = 1
var b: Int? = a //可以

Forced Unwrapping

在使用Optional變數或者常量之前,一定要使用if語句測試,看他們是否是nil,如果確認不是nil,那就可以進行Forced Unwrapping,也就是在Optional變數或者常量豁免適用!,以此向編譯器說明,你確定了該變數或者常量有值,可以放心使用:

var a: Int? = 1

if
a != nil { print(a!) //這裡如果不加!,輸出Optional(1),並且編譯器會有警告 }

為什麼對於Optional型別使用前要先監測呢?

因為如果不檢測就是用!求值,如果求出來的值是nil,會發生執行時錯誤:

var a: Int?
print(a!) //發生執行時錯誤

Optional Binding

文字解釋Optional Binding費勁,直接看程式碼:

var a: Int? = 1

if let b = a {  //if語句當中的let b = a這塊就是Optional Biding
    print(b)
} else {
    print("nil")
}

上面if語句當中的let b = a就是Optional Binding,如果a有值,那麼a的值會賦給b,否則,if語句不成立,將執行else語句。

這裡進行Optional Binding的時候,適用var b = a也是沒有問題的,但是由於編譯器發現你對b沒有改動,會出警告,提示你最好使用let。

另外一個需要注意的地方就是,這裡宣告的b,只能在if語句內部使用。

多個Optional Bindings可以一起使用,當中用逗號隔開就行,如果任何一個Optional Binding為nil,那麼if語句就不會執行:

var a: Int? = 1
var b: Int? = nil
if let c = a, let d = b {  //if語句當中的let b = a這塊就是Optional Biding 整個if語句輸出nil
    print("non nil")
} else {
    print("nil")
}

對於Optional Binding來說,出了在if語句當中使用,還可以在while語句當中使用。

Implicitly Unwrapped Optionals

前面提到過對於Optional型別的變數或者常量來說,無法直接賦值給非Optional的變數或者常量。但是有些時候,對於程式裡面的Optional型別,我們使用之前是可以肯定這個型別的變數或者常量是有值的,這時候如果進行Force Unwrapping就比較麻煩,這個時候就可以利用Implicitly Unwrapped Optionals了。一個變數或者常量宣告成Implicitly Unwrapped Optionals和宣告成Optional非常相似,只需要把?換成!:

var a: Int? //Optional
var b: Int! //Implicitly Unwrapped Optionals

編譯器對於Implicitly Unwrapped Optionals的使用是這樣的,首先把這個變數或者常量當成普通的Optional來對待,如果不行,那麼編譯器就自動進行Force-Unwrapping的操作:

var a: Int! = 2
var b = a //b型別是Optional的
var c: Int = a //無需對a顯示進行Fource-Wrapping加!

對於mplicitly Unwrapped Optionals需要注意,使用的時候千萬不能是nil的,否則會報執行時錯誤。