為什么會有Optional
OC中沒有Optional類型乱灵,OC中所有對象變量都可以為nil溯饵,因為nil
是無類型的指針。在OC中字典背镇、數(shù)組咬展、集合都不能放入nil
花履,nil
只能用在OC對象上面,變量在一定程度上來講便利性較差挚赊,但在Swift中卻不同诡壁。Swift中nil
和OC中的nil
是有很大區(qū)別的。在OC中nil
是指向一個不存在的對象的指針荠割,但是在Swift中妹卿,nil
不是指針,只是值缺失的特殊類型蔑鹦,任何類型可選項都可以設(shè)置為nil
夺克。所以在Swift中,可以用可選項值為nil
嚎朽,來表達變量的值缺失铺纽,增加了一定的便利性。
Swift中我們在變量類型后面添加 ?
來表示一個可選項哟忍,例如:
var name: String? = nil
Optional的實現(xiàn)
Optional其實是一個枚舉類型狡门,我們查看標準庫中代碼可以看到
@frozen public enum Optional<Wrapped> : ExpressibleByNilLiteral {
/// The absence of a value.
///
/// In code, the absence of a value is typically written using the `nil`
/// literal rather than the explicit `.none` enumeration case.
case none
/// The presence of a value, stored as `Wrapped`.
case some(Wrapped)
/// Creates an instance that stores the given value.
public init(_ some: Wrapped)
這個枚舉有兩個值,代碼Optional的兩層意思
- none
代表變量沒有值锅很,即為nil
- some
代表變量有值其馏,值為some
,some
包裝了實際了值
那Optional是如果得到實際的值呢爆安,還是來看標準庫中的代碼叛复,
/// The wrapped value of this instance, unwrapped without checking whether
/// the instance is `nil`.
///
/// The `unsafelyUnwrapped` property provides the same value as the forced
/// unwrap operator (postfix `!`). However, in optimized builds (`-O`), no
/// check is performed to ensure that the current instance actually has a
/// value. Accessing this property in the case of a `nil` value is a serious
/// programming error and could lead to undefined behavior or a runtime
/// error.
///
/// In debug builds (`-Onone`), the `unsafelyUnwrapped` property has the same
/// behavior as using the postfix `!` operator and triggers a runtime error
/// if the instance is `nil`.
///
/// The `unsafelyUnwrapped` property is recommended over calling the
/// `unsafeBitCast(_:)` function because the property is more restrictive
/// and because accessing the property still performs checking in debug
/// builds.
///
/// - Warning: This property trades safety for performance. Use
/// `unsafelyUnwrapped` only when you are confident that this instance
/// will never be equal to `nil` and only after you've tried using the
/// postfix `!` operator.
@inlinable public var unsafelyUnwrapped: Wrapped { get }
它是一個定義的get方法,Optionl通過unsafelyUnwrapped
來獲取實際的值扔仓,例如:
var ddb: String? = "冬冬吧"
let ddbCount = ddb.unsafelyUnwrapped.count
這樣就得到了變量的實際值褐奥。
Optional的使用
實現(xiàn)一個Optional
let ddb: Optional<String> = "冬冬吧"
// var ddb: String? = "冬冬吧"
我們這樣實現(xiàn)的可選項,實際上和注釋部分的類型后面加?
實現(xiàn)的是完全一樣的翘簇。
可選項的解包
可選項是不能直接使用的,需要解包后才能使用撬码,基本上有一下解包方式
-
!
強制解包,例如:
let count = ddb!.count
在強制解包前缘揪,你如果不知道它是否為nil
耍群,那你需要先對它進行非nil的判斷保護,否則強制解包一旦失敗找筝,程序會報錯蹈垢,如下代碼:
if ddb != nil {
let count = ddb!.count
print(count)
}
這樣即使我們使用了強制解包,但它的運行依然是安全的
-
if
判斷展開袖裕,例如:
if ddb != nil {
let count = ddb?.count
print(count ?? 0)
}
這里我們使用a ?? b
合并空值運算符的方式來解包曹抬,如果有值,則為count
急鳄,如果為nil
谤民,則默認0
使用合并控制運算符有兩個條件:
1.表達式a
必須是可選類型
2.表達式b
必須和a
的處處類型相同
- 使用可選項綁定的方式
if let ddbStr = ddb {
let count = ddbStr.count
print(count)
}
使用可選項綁定來判斷可選項是否有值堰酿,如果有就賦值給臨時變量。同一個if
語句可以有多個可選項綁定张足,用, 分開即可
小結(jié)
Optional,是”不存在“或“空”概念的加強版本触创。而nil
則是“不存在”的基礎(chǔ)版本
在swift中引入optional
的目的,就是將"不存在"這個概念綁定到具體的類型上为牍。optional.nil
指向的是值的“不存在”哼绑,同時表示:如有值只能是optional.some<T>
中的T類型,將所有類型的值空間進行了nil的擴展碉咆。