💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
# Swift 可选项 > 原文: [https://www.programiz.com/swift-programming/optionals](https://www.programiz.com/swift-programming/optionals) #### 在本文中,您将学习可选项,其用例以及 Swift 中的可选项处理。 在上一篇文章中,我们了解了 Swift 中可用的不同数据类型,并且还注意到这些类型声明的变量或常量包含默认值。 **示例**: ```swift let someValue = Int() print(someValue) ``` 运行该程序时,输出为: ```swift 0 ``` 但是,Swift 中还有另一种称为`Optional`的数据类型,其默认值为空值(`nil`)。 如果希望变量或常量中不包含任何值,则可以使用可选项。 可选项可以包含一个值或不存在一个值(空值)。 从技术上讲,您可以认为它是可选的鞋盒。 鞋盒中可能装有鞋,也可能没有。 因此,从包装箱中取出鞋子时,您应该事先知道。 * * * ## 如何声明`Optional`? 通过将`!`或`?`附加到`Type`,您可以简单地将数据类型表示为`Optional`。 如果一个可选参数中包含一个值,则返回值为`Optional<Value>`,否则返回`nil`。 ### 示例 1:如何在 Swift 中声明一个可选项? ```swift var someValue:Int? var someAnotherValue:Int! print(someValue) print(someAnotherValue) ``` 运行该程序时,输出为: ```swift nil nil ``` 在上面的程序中,我们使用`?`和`!`初始化了一个可选项。 两种方法都是可以创建可选项的方法,但是有一个主要的不同,我们将在下面进行探讨。 声明一个可选的`Int`意味着该变量将具有整数值或无值。 由于没有为变量分配任何值,因此您可以在屏幕上看到两个`print`语句输出`nil`。 * * * ### 示例 2:从可选项分配和访问值 ```swift let someValue:Int? = 5 print(someValue) print(someValue!) ``` 运行该程序时,输出为: ```swift Optional(5) 5 ``` 在上面的程序中,我们声明了`Int`类型的可选项,并在其中分配了值 5。 如您所见,将可选项打印为`print(someValue)`不会给您`5`而是`Optional(5)`。 它具有上述形式:`Optional<Value>`。 为了从中访问`<Value>`,我们需要一种称为**展开**的机制。 您可以通过在变量/常量的末尾附加`!`字符来展开可选字符,如下一行`print(someValue!)`所示。`print(someValue!)`打开包装,并在屏幕上输出`5`。 但是,请记住,仅当确定在访问可选项时肯定具有值时,才应使用这种解包机制。 * * * ### 示例 3:显式声明一个未包装的可选项 您还可以通过以下方式创建解包后的可选项: ```swift let someValue:Int! = 5 print(someValue) ``` 运行该程序时,输出为: ```swift 5 ``` 在上面的程序中,`Int!`创建一个未包装的可选项,当您访问它时,它会自动对值进行包装,因此您不必每次都附加`!`字符。 请确保在使用这些可选项时,变量在访问它时始终需要有一个值。 如果不这样做,将会导致致命的错误崩溃。 * * * ### 示例 4:访问`null`的未包装可选对象时发生致命错误 ```swift var someValue:Int! var unwrappedValue:Int = someValue //crashes due to this line ``` 当您运行该程序时,您会因**致命错误**而崩溃:在解开可选项时意外发现`nil`,因为代码`unwrappedValue:Int = someValue`试图将可选`someValue`中的值赋给变量`unwrappedValue`。 但是,`somevalue`是包含`nil`值的`Optional`类型。 尝试将`nil`值分配给变量`unwrappedValue`(这不是可选的)会导致崩溃。 有多种处理此情况的技术,下面将进行说明。 * * * ## 可选项处理 为了使用可选项,需要将其解包。 使用可选项的更好方法是通过条件展开而不是使用`!`运算符强制展开。 这是因为有条件的展开询问**检查此变量是否具有值?**。 如果是,请提供该值,否则将处理`nil`情况。 相反,强制展开表示**该变量在使用时确实有一个值**。 因此,当您强制解开一个`nil`的变量时,您的程序将在解开可选异常并抛出的同时抛出**意外发现的`nil`**。 下面说明了一些用于条件展开的技术: ### 1\. `If`语句 您可以使用`if`语句,然后将可选参数与`nil`进行比较,以找出可选参数是否包含值。 您可以在`if`语句中使用比较运算符“等于”运算符(`==`)或“不等于”运算符(`!=`)。 #### 示例 5:`if else`语句的可选项处理 ```swift var someValue:Int? var someAnotherValue:Int! = 0 if 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") } ``` 运行该程序时,输出为: ```swift doesn't contain value It has some value 0 ``` 在上面的程序中,如果可选项包含值,则执行`if`语句内的代码,否则执行`else`块内的语句。 使用此技术进行可选项处理的主要缺点是,您仍然需要使用`!`运算符从可选项中解包该值。 * * * ### 2.可选绑定(如果允许) 可选绑定可帮助您找出可选项是否包含值。 如果可选项包含一个值,则该值可用作临时常量或变量。 因此,可以将可选绑定与`if`语句一起使用,以检查可选项内部的值,并在单个操作中将该值提取到常量或变量中。 #### 示例 5:使用`if let`语句的可选项处理 ```swift var someValue:Int? var someAnotherValue:Int! = 0 if 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") } ``` 运行该程序时,输出为: ```swift doesn't contain value It has some value 0 ``` 在上面的程序中,如果可选项包含一个值,则执行`if`语句中的代码。 否则,`else`块将被执行。`if-let`语句还自动展开该值,并将展开后的值放入`temp`常量中。 该技术的主要优势在于,尽管可以确定某个可选项包含一个值,但您无需强行解开该值。 * * * ### 3.`guard`语句 您可以使用`guard`处理 Swift 中的可选项。 如果您不知道什么警卫,请不要担心。 现在,仅将警卫视为没有`if`块的`if-else`条件。 如果条件失败,则执行`else`语句。 如果不是,则执行下一条语句。 有关更多详细信息,请参见 [Swift `Guard`](/swift-programming/guard-statement "Swift guard statement")。 #### 示例 6:使用`guard`的可选项处理 ```swift func testFunction() { let someValue:Int? = 5 guard let temp = someValue else { return } print("It has some value \(temp)") } testFunction() ``` 运行该程序时,输出为: ```swift It has some value 5 ``` 在上述程序中,防护包含一个条件,即可选的`someValue`是否包含值。 如果它包含一个值,则`guard-let`语句将自动解包该值,并将解包后的值放入`temp`常量中。 否则,`else`块将被执行,它将返回到调用函数。 由于可选项包含一个值,因此将调用`print`函数。 * * * ### 4.`nil`折叠运算符 在 Swift 中,您还可以使用`nil`折叠运算符检查可选变量是否包含值。 定义为`(a ?? b)`。 它解开可选的`a`并返回它(如果它包含一个值),或者如果`a`为零,则返回默认值`b`。 #### 示例 7:使用`nil`折叠运算符的可选项处理 ```swift var someValue:Int! let defaultValue = 5 let unwrappedValue:Int = someValue ?? defaultValue print(unwrappedValue) ``` 运行该程序时,输出为: ```swift 5 ``` 在上面的程序中,变量`someValue`定义为项,并且包含`nil`值。 `nil`合并运算符无法解开可选项,因此返回`defaultValue`。 因此,语句`print(unwrappedValue)`在控制台中输出 5。 ```swift var someValue:Int? = 10 let defaultValue = 5 let unwrappedValue:Int = someValue ?? defaultValue print(unwrappedValue) ``` 运行该程序时,输出为: ```swift 10 ``` 但是,在上述程序中,可选变量`someValue`初始化为值 10。因此,nil 合并运算符成功地从`someValue`中解包了该值。 因此,语句`someValue ?? defaultValue`返回 10,并且语句`print(unwrappedValue)`在控制台中输出 10。