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)
结果如下:
nil
nil
在上面的程序中,我们已经使用初始化了可选类型?和这两种方法都可以创建可选类型的,但有一个主要区别,我们将在下面探讨。
声明可选整数意味着变量将具有整数值或没有值。由于没有给变量赋值,所以您可以在屏幕上看到两个 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)的机制。
您可以通过在变量/常量末尾附加 !
字符来解包一个可选类型,如下一行 print(someValue!)
。print(someValue!)
解包可选类型并在屏幕上输出 5。
但是,请记住,只有当您确定在访问可选类型时,该可选类型一定会有值时,才应使用这种解包机制。
实例 3:显式声明解包的可选类型
您还可以创建一个未解包的可选项,如下所示:
let someValue:Int! = 5
print(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! = 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-let)
可选绑定帮助您确定可选项是否有值。如果可选类型有值,则该值可用作临时常量或变量。因此,可选绑定可以与 if
语句一起使用,以检查可选类型中的值,并在单个操作中将该值提取为常量或变量。
if-let 语句的可选处理" class="reference-link">实例 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 中,您可以使用 guard
来处理可选类型。如果你不知道 guard
是什么,不要担心。现在,只需将 guard
视为一个没有 if
的 if-else
条件。如果条件失败,则执行 else
语句。如果不是,则执行下一个语句。有关更多详细信息,请参阅 Swift guard。
实例 6:使用 guard let 的可选处理
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
代码的内容,然后返回调用函数。由于可选项类型有值,因此调用 print
函数。
4. 空合运算符(Nil-coalescing operator)
在 Swift 中,还可以使用空合运算符检查可选类型是否有值。其定义为(a??b
)。它解包可选的 a
并返回它(如果它有值),或者如果 a
为零则返回默认值 b
。
实例 7:使用空合运算符的可选处理
var someValue:Int!
let defaultValue = 5
let unwrappedValue:Int = someValue ?? defaultValue
print(unwrappedValue)
结果如下:
5
在上面的程序中,变量 someValue
被定义为可选的,并且包含 nil
值。空合运算符无法解包可选值,因此返回默认值。因此,语句 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。