Swift 可選類型(Optional)

在本文中,您將學習可選,其用例以及Swift中的可選處理。

在上一篇文章中,我們了解了Swift中可用的不同數(shù)據(jù)類型,并且還注意到這些類型聲明的變量或常量包含默認值。

例:

let someValue = Int()
print(someValue)

運行該程序時,輸出為:

0

但是,Swift中還有另一種稱為 Optional 的數(shù)據(jù)類型,其默認值為空值(nil)。如果希望變量或常量中不包含任何值,則可以使用 Optional。可選類型可以包含一個值或不存在一個值(空值)。

從技術上講,您可以認為它是可選的鞋盒。鞋盒中可能裝有鞋,也可能沒有。因此,從包裝箱中取出鞋子時,您應該事先知道。

如何聲明一個可選的?

您可以通過追加將數(shù)據(jù)類型簡單地表示為 Optional。 方法是類型附加! 或 ?。 如果可選變量中包含一個值,則將其值返回為 Optional <Value>,否則返回nil。

示例1:如何在Swift中聲明一個可選的?

var someValue:Int?
var someAnotherValue:Int!
print(someValue)
print(someAnotherValue)

運行該程序時,輸出為:

nil
nil

在上面的程序中,我們使用 ? 和 ! 初始化了一個可選類型。兩種方法都可以創(chuàng)建可選的方法,但是有一個主要的不同,我們將在下面進行探討。

聲明一個可選的 Int 意味著該變量將具有整數(shù)值或無值。由于沒有為變量分配任何值,因此您可以在屏幕上看到兩個print語句輸出nil。

示例2:從可選對象分配和訪問值

let someValue:Int? = 5
print(someValue)
print(someValue!)

運行該程序時,輸出為:

Optional(5)
5

在上面的程序中,我們聲明了一個可選Int類型,并在其中分配了值5。

將可選打印為print(someValue)不會給您返回5,而是為Optional(5)。 它具有如上所述的形式:Optional <Value>。 為了從中訪問<Value>,我們需要一種稱為解包(unwrapping)的機制。

您可以通過在變量/常量的末尾附加字符 ! 來展開可選內(nèi)容,如下一行所示 print(someValue!)。print(someValue!) 解開可選內(nèi)容并在屏幕上輸出 5。

但是,請記住,僅當確定在訪問可選選項時肯定具有值時,才應使用這種解包機制。

示例3:顯式聲明一個未包裝的可選

您還可以通過以下方式創(chuàng)建解包后的可選內(nèi)容:

let someValue:Int! = 5
print(someValue)

運行該程序時,輸出為:

5

在上面的程序中,Int! 創(chuàng)建一個未包裝的可選內(nèi)容,當您訪問它時,它會自動解包該值,因此您不必每次都!字符。

請確保在使用這些可選選項時,變量在訪問時始終需要有一個值。如果不這樣做,將會導致致命的錯誤崩潰。

示例4:訪問null的未包裝可選對象時發(fā)生致命錯誤

var someValue:Int!
var unwrappedValue:Int = someValue //crashes due to this line

當您運行該程序時,您將得到致命錯誤的崩潰:解開Optional值時意外發(fā)現(xiàn)nil,因為代碼unwrappedValue:Int = someValue試圖將Optional someValue中的值分配給變量unwrappedValue。

但是,somevalue 是一個包含 nil 值的可選類型。試圖將 nil 值分配給變量 unwrappedValue (這不是一個Optional)將導致崩潰。

下面將說明處理此情況的不同方法。

可選處理

為了使用可選值,需要將其解包。使用可選值的更好方法是通過條件解包,而不是使用 ! 運算符強制解包。

這是因為有條件的展開詢問是否檢查此變量是否有值?。如果是,請?zhí)峁┰撝?,否則將處理nil情況。

相反,強制展開表示此變量在使用時確實具有一個值。 因此,當您強制解開一個nil的變量時,您的程序?qū)⒃诮忾_一個可選異常并崩潰時拋出意外發(fā)現(xiàn)的nil。下面說明了一些用于條件展開的技巧:

1.if 語句

您可以使用if語句,然后將可選參數(shù)與nil進行比較,以找出可選參數(shù)是否包含值。您可以在if語句中使用比較運算符“等于”運算符(==)或“不等于”運算符(!=)。

示例5:if else語句的可選處理

var someValue:Int?
var someAnotherValue:Int! = 0
        
if someValue != nil {
	print("包含值 \(someValue!)")
} else {
	print("不包含值")
}
        
if someAnotherValue != nil {
	print("包含值 \(someAnotherValue!)")
} else {
	print("不包含值")
}

運行該程序時,輸出為:

不包含值
包含值 0

在上面的程序中,如果可選語句包含值,則執(zhí)行if語句內(nèi)的代碼,否則執(zhí)行else塊內(nèi)的語句。使用此方法進行可選處理的主要缺點是,您仍然需要從可選中使用 ! 運算符解包該值。

2.可選綁定(if let)

可選綁定可幫助您找出可選值是否包含值。如果可選值包含一個值,則該值可用作臨時常量或變量。因此,可以將可選綁定與if語句一起使用,以檢查可選內(nèi)部的值,并在單個操作中將其提取為常量或變量。

示例5:使用if let語句的可選處理

var someValue:Int?
var someAnotherValue:Int! = 0
       
if let temp = someValue {
	print("包含值 \(temp)") 
} else {
	print("不包含值")
}
        
if let temp = someAnotherValue {
	print("包含值  \(temp)")
} else {
	print("不包含值")      
}

運行該程序時,輸出為:

不包含值
包含值 0

在上面的程序中,如果可選語句包含一個值,則執(zhí)行if語句中的代碼。否則,else塊將被執(zhí)行。if-let語句還自動解開該值,并將解開后的值存儲在temp常量中。該方法的主要優(yōu)勢在于,盡管可以確定某個可選內(nèi)容包含一個值,但您無需強行解開該值。

3.Guard 語句

您也可以在Swift中使用 guard 語句 處理可選內(nèi)容。如果您不知道什么是 guard,請不要擔心?,F(xiàn)在,僅將guard視為if-else沒有if阻止的條件。如果條件失敗,則執(zhí)行else語句。如果不是,則執(zhí)行下一條語句。有關更多詳細信息,請參見Swift Guard

示例6:使用Guard的可選處理

func testFunction() {
	let someValue:Int? = 5
	guard let temp = someValue else {
		return
	}
	print("It has some value \(temp)")
}

testFunction()

運行該程序時,輸出為:

It has some value 5

在上面的程序中,guard 包含一個條件,即可選的 someValue 是否包含一個值。如果它包含一個值,那么 guard-let 語句將自動解包該值并將解包的值放置在 temp 常量中。否則,else 塊將被執(zhí)行,并且它將返回到調(diào)用函數(shù)。因為可選項包含一個值,所以調(diào)用 print 函數(shù)。更多細節(jié)請參見Swift guard。

4.空合運算符(??)

在Swift中,您還可以使用空合運算符運算符檢查可選項是否包含值。 它被定義為(a??b)。 它展開一個可選的a,如果它包含一個值,則返回它,或者如果a為空,則返回默認值b。

示例7:使用空合運算符的可選處理

var someValue:Int!
let defaultValue = 5
let unwrappedValue:Int = someValue ?? defaultValue
print(unwrappedValue)

運行該程序時,輸出為:

5

在上面的程序中,變量someValue定義為可選,并且包含nil值。 空合運算符無法解開可選值,因此返回defaultValue。 因此,語句print(unwrappedValue)在控制臺中輸出5。

var someValue:Int? = 10
let defaultValue = 5
let unwrappedValue:Int = someValue ?? defaultValue
print(unwrappedValue)

運行該程序時,輸出為:

10

但是,在上述程序中,可選變量someValue被初始化為值10。因此,空合運算符成功地從中解包了該值someValue。因此,該語句在控制臺臺中someValue ?? defaultValue返回10,語句print(unwrappedValue)輸出10。

丰满人妻一级特黄a大片,午夜无码免费福利一级,欧美亚洲精品在线,国产婷婷成人久久Av免费高清