什么是“!"和 '?'在 Swift 中使用的标记 [英] What are '!' and '?' marks used for in Swift
问题描述
当我从 Objective-C
改为 Swift
编程时,我遇到了 '!
'(感叹号)和 '>?
'(问号),通常必须放在 property
、method
调用等之后.这些标记的用途是什么?如果我们不使用它们会发生什么?
When I changed from Objective-C
to Swift
programming, I have come across '!
' (exclamation mark) and '?
' (question mark) that often have to be put right after a property
, a method
call etc. What are these marks used for, and what happens if we did not use them?
我在网上搜索了彻底的答案,但找不到任何答案.所以我决定把我的答案放在这里,以防有人为此寻找明确的答案.
I searched for a thorough answer on the web but could not find any. So I decided to put here my answer in case for anyone is in search of a clear answer for that.
我还在下面的回答中包含了一个指向与我的问题类似的问题的链接,您可以在其中找到有关如何以及在何处使用这些标记(即!"和?")的进一步说明.我的问题提出了,我的回答比链接中的类似问题在更基本的层面上进行了解释.
I also included in my answer below a link to a question that is similar to mine, where you can find further explanation on how and where you can use these marks (i.e. '!' and '?'). My question asks and my answer explains at a more basic level than the similar question in the link.
推荐答案
用于这些标记的术语是 Optional Chaining
.它们一般用于区分情况,例如,一个property
是否是,一个方法调用
返回nil
.
The terminology used for these marks is Optional Chaining
. They are generally used for distinguishing the cases, for example, whether a property
is, a method call
returns nil
.
Apple 的语言指南中解释的示例 Optional Chaining
很好地展示了它们的用途:
An example explained in Apple's language guide for Optional Chaining
is a good one to show the purpose of their use:
首先定义了两个名为Person
和Residence
的类:
First, two classes called
Person
andResidence
are defined:
class Person {
var residence: Residence?
}
class Residence {
var numberOfRooms = 1
} Residence instances have a single `Int` property called `numberOfRooms`, with a default value of **1**. `Person` instances
有一个可选的 residence
属性,类型为 Residence
?.
have an optional residence
property of type Residence
?.
如果你创建一个新的 Person
实例,它的 residence
属性是由于是可选的,默认初始化为 nil
.在代码中下面,john
的 residence
属性值为 nil
:
If you create a new Person
instance, its residence
property is
default initialized to nil
, by virtue of being optional. In the code
below, john
has a residence
property value of nil
:
let john = Person()
如果您尝试访问此人的 numberOfRooms
属性residence
,通过在 residence
后面放置一个感叹号强制展开其值,您会触发运行时错误,因为没有要解包的 residence
值:
If you try to access the numberOfRooms
property of this person’s
residence
, by placing an exclamation mark after residence
to
force the unwrapping of its value, you trigger a runtime error,
because there is no residence
value to unwrap:
let roomCount = john.residence!.numberOfRooms
// this triggers a runtime error
当 john.residence
有一个 non-nil 值时,上面的代码成功并将 roomCount
设置为包含适当的 Int
值房间的数量.但是,此代码始终触发 运行时错误,当residence
为nil
时,如上图所示.
The code above succeeds when john.residence
has a non-nil value
and will set roomCount
to an Int
value containing the appropriate
number of rooms. However, this code always triggers a runtime
error when residence
is nil
, as illustrated above.
可选链提供了一种访问值的替代方法房间数
.要使用可选链,请在感叹号的位置:
Optional chaining provides an alternative way to access the value of
numberOfRooms
. To use optional chaining, use a question mark in
place of the exclamation mark:
if let roomCount = john.residence?.numberOfRooms {
print("John's residence has \(roomCount) room(s).")
} else {
print("Unable to retrieve the number of rooms.")
}
// Prints "Unable to retrieve the number of rooms."
这告诉 Swift 在可选的 residence
属性上chain"并在 residence
存在时检索 numberOfRooms
的值.
This tells Swift to "chain" on the optional residence
property
and to retrieve the value of numberOfRooms
if residence
exists.
因为尝试访问 numberOfRooms
有可能失败,可选链接尝试返回 Int?
类型的值,或可选 Int".当 residence
为 nil
时,如示例所示上面这个可选的Int
也将是nil
,以反映事实无法访问 numberOfRooms
.可选的 Int
通过可选绑定访问以解开整数并分配roomCount
变量的非可选值.
Because the attempt to access numberOfRooms
has the potential to
fail, the optional chaining attempt returns a value of type Int?
, or
"optional Int". When residence
is nil
, as in the example
above, this optional Int
will also be nil
, to reflect the fact
that it was not possible to access numberOfRooms
. The optional Int
is accessed through optional binding to unwrap the integer and assign
the nonoptional value to the roomCount
variable.
请注意,即使 numberOfRooms
是一个 非可选Int
.通过可选链查询的事实意味着对 numberOfRooms
的调用将始终返回 Int?
而不是Int
.
Note that this is true even though numberOfRooms
is a nonoptional
Int
. The fact that it is queried through an optional chain means
that the call to numberOfRooms
will always return an Int?
instead
of an Int
.
您可以将 Residence
实例分配给 john.residence
,以便它不再有 nil
值:
You can assign a Residence
instance to john.residence
, so that it
no longer has a nil
value:
john.residence = Residence()
除了上面对可选链的一般概述之外,您还可以查看 StackOverflow 中的这个答案.
Besides the general overview of Optional Chaining above, you can look at this answer in StackOverflow.
希望这能让您对可选链有所了解.
Hope this gives you some perspective on Optional Chaining.
这篇关于什么是“!"和 '?'在 Swift 中使用的标记的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!