📜  Swift可选

📅  最后修改于: 2020-10-09 15:59:14             🧑  作者: Mango

在本文中,您将学习可选,其用例以及Swift中的可选处理。

在上一篇文章中,我们了解了Swift中可用的不同数据类型,并且还注意到这些类型声明的变量或常量包含默认值。

例:

let someValue = Int()
print(someValue)

运行该程序时,输出为:

0

但是,Swift中还有另一种数据类型称为Optional,其默认值为null值( nil )。如果希望变量或常量中不包含任何值,则可以使用可选。可选类型可以包含一个值或不存在一个值(空值)。

从技术上讲,您可以认为它是可选的鞋盒。鞋盒中可能装有鞋,也可能没有。因此,从包装箱中取出鞋子时,您应该事先知道。


如何声明一个可选的?

您可以通过追加将数据类型简单地表示为Optional !还是?Type 。如果一个可选参数中包含一个值,则将其值返回为Optional ,否则返回nil

示例1:如何在Swift中声明一个可选的?

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

运行该程序时,输出为:

nil
nil

在上面的程序中,我们使用?初始化了一个可选类型?! 。两种方法都可以创建可选的方法,但是有一个主要的不同,我们将在下面进行探讨。

声明一个可选的Int意味着该变量将具有整数值或无值。由于没有为变量分配任何值,因此您可以在屏幕上看到两个print语句输出nil


示例2:从可选对象分配和访问值

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

运行该程序时,输出为:

Optional(5)
5

在上面的程序中,我们声明了一个Int类型的可选对象,并在其中分配了值5。

如您所见,将可选选项print(someValue)print(someValue)不会给您5而是Optional(5) 。它具有如上所述的形式: Optional 。为了从中访问 ,我们需要一种称为unwrapping的机制。

您可以通过追加来打开可选项!变量/常量末尾的字符 ,如下一行print(someValue!)print(someValue!)解开可选内容,并在屏幕上输出5

但是,请记住,仅当确定在访问可选选项时肯定具有值时,才应使用这种解包机制。


示例3:显式声明一个未包装的可选

您还可以通过以下方式创建解包后的可选内容:

let someValue:Int! = 5
print(someValue)

运行该程序时,输出为:

5

在上面的程序中, Int!创建一个未包装的可选内容,当您访问它时,它会自动解包该值,因此您不必每次都附加! 字符。

请确保在使用这些可选选项时,变量在访问时始终需要有一个值。如果不这样做,将会导致致命的错误崩溃。


示例4:访问null的未包装可选对象时发生致命错误

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

当您运行该程序时,您将得到致命错误的崩溃 unwrappedValue:Int = someValue Optional值时意外发现nil,因为代码unwrappedValue:Int = someValue试图将Optional someValue中的值分配给变量unwrappedValue

但是, somevalue是包含nil值的Optional类型。尝试将nil值分配给变量unwrappedValue(这不是可选的)会导致崩溃。

有多种处理此情况的技术,下面将进行说明。


可选处理

为了使用可选值,需要将其解包。使用可选值的更好方法是通过条件展开,而不是使用!强制展开! 运算符。

这是因为有条件的展开询问是否检查此变量是否有值? 。如果是,请提供该值,否则将处理nil情况。

相反,强制展开表示此变量在使用时确实具有一个值 。因此,当您强制解开一个nil的变量时,您的程序将在解开一个可选异常并崩溃时抛出意外发现的nil 。下面说明了一些用于条件展开的技术:

1.陈述

您可以使用if语句,然后将可选参数与nil进行比较,以找出可选参数是否包含值。您可以使用比较运算符 “等于” 运算符 ( == )或“不等于” 运算符 ( != )if语句。

示例5:if else语句的可选处理
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")
}

运行该程序时,输出为:

doesn't contain value
It has some value 0

在上面的程序中,如果可选语句包含值,则执行if语句内的代码,否则执行else块内的语句。使用此技术进行可选处理的主要缺点是,您仍然需要从可选使用中解开值! 运算符。


2.可选绑定(如果允许)

可选绑定可帮助您找出可选值是否包含值。如果可选值包含一个值,则该值可用作临时常量或变量。因此,可以将可选绑定与if语句一起使用,以检查可选内部的值,并在单个操作中将其提取为常量或变量。

示例5:使用if let语句的可选处理
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")      
}

运行该程序时,输出为:

doesn't contain value
It has some value 0

在上面的程序中,如果可选语句包含一个值,则执行if语句中的代码。否则,else块将被执行。 if-let语句还可以自动解包该值,并将解包后的值放在temp常量中。该技术的主要优势在于,尽管可以确定某个可选内容包含一个值,但您无需强行解开该值。


3.警卫声明

您可以使用guard在Swift中处理可选内容。如果您不知道什么警卫,请不要担心。现在,仅将警卫视为没有if块的if-else条件。如果条件失败,则执行else语句。如果不是,则执行下一条语句。有关更多详细信息,请参见Swift Guard。

示例6:使用防护罩的可选处理
func testFunction() {
    let someValue:Int? = 5
    guard let temp = someValue else {
        return
    }
    print("It has some value \(temp)")
}

testFunction()

运行该程序时,输出为:

It has some value 5

在上面的程序中,警卫队包含一个条件,即可选的someValue是否包含一个值。如果它包含一个值,则guard-let语句将自动解包该值并将解包后的值放入临时常量中。否则,else块将被执行,它将返回到调用函数。由于可选内容包含一个值,因此将调用print 函数 。


4.无销售运算符

在Swift中,您还可以使用nil-coalescing 运算符检查可选变量是否包含值。它定义为(a ?? b) 。它解开可选的a并返回它(如果它包含一个值),或者返回一个默认值b(如果a为零)。

示例7:使用nil-coalescing 运算符的可选处理
var someValue:Int!
let defaultValue = 5
let unwrappedValue:Int = someValue ?? defaultValue
print(unwrappedValue)

运行该程序时,输出为:

5

在上面的程序中,变量someValue定义为可选,并且包含nil值。 nil合并运算符无法解开可选内容,因此返回defaultValue 。因此,语句print(unwrappedValue)在控制台中输出5。

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

运行该程序时,输出为:

10

但是,在上述程序中,可选变量someValue初始化为值10。因此,nil合并运算符成功地将值从someValue中解包 。因此,声明someValue ?? defaultValue返回10,语句print(unwrappedValue)在控制台中输出10。