Swift 可选类型(Optionals)
在本文中,您将了解可选类型、其用例和 Swift 中的可选处理。
在上一篇文章中,我们了解了 Swift 中可用的不同数据类型,并注意到这些类型的变量或常量包含默认值。
let someValue = Int()print(someValue)
结果如下:
0
然而,Swift 中还有另一种称为 Optional 的数据类型,其默认值为空值(nil)。如果希望变量或常量中不包含任何值,则可以使用 optional。可选类型可以有值,也可以没有值(空值)。
如何声明可选类型?
您可以简单地通过在类型后附加 ! 或 ? 将数据类型表示为可选类型。如果可选类型中有值,则返回值为 Optional<Value>,否则返回 nil。
实例 1:如何在 Swift 中声明可选类型?
var someValue:Int?var someAnotherValue:Int!print(someValue)print(someAnotherValue)
结果如下:
nilnil
在上面的程序中,我们已经使用初始化了可选类型?和这两种方法都可以创建可选类型的,但有一个主要区别,我们将在下面探讨。
声明可选整数意味着变量将具有整数值或没有值。由于没有给变量赋值,所以您可以在屏幕上看到两个 print 语句输出 nil。
实例 2:从可选项中赋值和访问值?
let someValue:Int? = 5print(someValue)print(someValue!)
结果如下:
Optional(5)5
在上面的程序中,我们声明了一个可选的 Int 类型,并在其中赋值 5。
如您所见,print(someValue) 并不会给出 5,而是 Optional(5)。它的形式如上所述:Optional<Value>。为了从中访问 <Value>,我们需要一种称为解包(unwrapping)的机制。
您可以通过在变量/常量末尾附加 ! 字符来解包一个可选类型,如下一行 print(someValue!)。print(someValue!) 解包可选类型并在屏幕上输出 5。
但是,请记住,只有当您确定在访问可选类型时,该可选类型一定会有值时,才应使用这种解包机制。
实例 3:显式声明解包的可选类型
您还可以创建一个未解包的可选项,如下所示:
let someValue:Int! = 5print(someValue)
结果如下:
5
在上述程序中,Int!创建一个解包的可选类型,当您访问该值时,它会自动打开该值,这样您就不需要每次附加 ! 字符。
实例 4:访问解包可选类型时出现致命错误
var someValue:Int!var unwrappedValue:Int = someValue //crashes due to this line
当您运行程序时,会出现致命错误:在解包可选值时意外发现 nil,因为代码unwrappedValue:Int = someValue 试图将可选 someValue 的值赋给变量 unwrappeValue。
但是,somevalue 是包含 nil 值的可选类型。尝试将 nil 值赋值给变量 unwrappedValue(非可选)将导致崩溃。
可以不同的技术来处理这种情况,如下所述。
可选类型处理
为了使用可选类型,需要将其解包。使用可选类型的更好方法是使用条件解包,而不是使用 ! 运算符强制解包。
这是因为有条件解包要求检查此变量是否有值。如果是,请给出值,否则将处理 nil 情况。
相反,强制解包表示在使用该变量时,该变量确实有一个值。因此,当您强制解包一个为 nil 的变量时,您的程序将在展开可选异常和崩溃时抛出意外发现的 nil。条件解包的一些技术解释如下:
1.If 语句
可以使用 if 语句并将 optional 与 nil 进行比较,以确定 optional 是否有值。您可以在 if 语句中使用比较运算符"等于"运算符(=)或”不等于”运算符(!=)。
实例 5:可选类型处理 if-else 语句
var someValue:Int?var someAnotherValue:Int! = 0if someValue != nil {print("It has some value \(someValue!)")} else {print("doesn't contain value")}if someAnotherValue != nil {print("It has some value \(someAnotherValue!)")} else {print("doesn't contain value")}
结果如下:
doesn't contain valueIt has some value 0
在上述程序中,如果可选类型有值,则执行 if 语句中的代码,否则执行 else 块中的语句。使用此技术的可选处理的主要缺点是,您仍然需要使用 ! 运算符从可选类型这中解包值。
2.可选绑定(if-let)
可选绑定帮助您确定可选项是否有值。如果可选类型有值,则该值可用作临时常量或变量。因此,可选绑定可以与 if 语句一起使用,以检查可选类型中的值,并在单个操作中将该值提取为常量或变量。
if-let 语句的可选处理" class="reference-link">实例 5:使用 if-let 语句的可选处理
var someValue:Int?var someAnotherValue:Int! = 0if let temp = someValue {print("It has some value \(temp)")} else {print("doesn't contain value")}if let temp = someAnotherValue {print("It has some value \(temp)")} else {print("doesn't contain value")}
结果如下:
doesn't contain valueIt has some value 0
在上述程序中,如果可选类型有值,则执行 if 语句中的代码。否则执行 else。if let 语句还自动解包,并将解包的值放置在 temp 常量中。这种技术具有主要优势,因为您不需要强制解包值,尽管可以确定可选类型是有值的。
3. Guard 语句
在 Swift 中,您可以使用 guard 来处理可选类型。如果你不知道 guard 是什么,不要担心。现在,只需将 guard 视为一个没有 if 的 if-else 条件。如果条件失败,则执行 else 语句。如果不是,则执行下一个语句。有关更多详细信息,请参阅 Swift guard。
实例 6:使用 guard let 的可选处理
func testFunction() {let someValue:Int? = 5guard let temp = someValue else {return}print("It has some value \(temp)")}testFunction()
结果如下:
It has some value 5
在上述程序中,guard 包含一个条件,即可选的 someValue 是否有值。如果它包含一个值,则 guard let 语句将自动解包该值,并将解包的值放置在 temp 常量中。否则,执行 else 代码的内容,然后返回调用函数。由于可选项类型有值,因此调用 print 函数。
4. 空合运算符(Nil-coalescing operator)
在 Swift 中,还可以使用空合运算符检查可选类型是否有值。其定义为(a??b)。它解包可选的 a 并返回它(如果它有值),或者如果 a 为零则返回默认值 b。
实例 7:使用空合运算符的可选处理
var someValue:Int!let defaultValue = 5let unwrappedValue:Int = someValue ?? defaultValueprint(unwrappedValue)
结果如下:
5
在上面的程序中,变量 someValue 被定义为可选的,并且包含 nil 值。空合运算符无法解包可选值,因此返回默认值。因此,语句 print(unwrappedValue) 在控制台中输出 5。
var someValue:Int? = 10let defaultValue = 5let unwrappedValue:Int = someValue ?? defaultValueprint(unwrappedValue)
结果如下:
10
然而,在上面的程序中,可选变量 someValue 被初始化为 10。因此,空合运算符成功地从 someValue 中解包该值。因此,声明 someValue??defaultValue 返回 10,语句 print(unwrappedValue) 在控制台中输出 10。