什么是 '!'和 '?' Swift 中使用的标记
What are '!' and '?' marks used for in Swift
当我从Objective-C
转为Swift
编程时,我遇到了'!
'(感叹号)和'?
'(问号)通常必须紧跟在 property
、method
调用等之后。这些标记有什么用,如果我们不使用它们会怎样?
我在网上搜索了详尽的答案,但没有找到。所以我决定把我的答案放在这里,以防有人为此寻找明确的答案。
我还在下面的回答中包含了一个 link 与我的问题类似的问题,您可以在其中找到有关如何以及在何处使用这些标记(即“!”和“?”)的进一步解释。 ').我的问题和我的回答比 link.
中的类似问题更基本
这些标记使用的术语是 Optional Chaining
。它们一般用于区分大小写,例如,a property
是否是,a method call
returns nil
.
Apple's language guide for Optional Chaining
中解释的一个例子很好地说明了它们的用途:
First, two classes called Person
and Residence
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
have an optional residence
property of type Residence
?.
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()
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
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."
This tells Swift to “chain” on the optional residence
property
and to retrieve the value of numberOfRooms
if residence
exists.
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.
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
.
You can assign a Residence
instance to john.residence
, so that it
no longer has a nil
value:
john.residence = Residence()
除了上面对可选链的一般概述之外,您还可以在 Whosebug 中查看此answer。
希望这能让您对可选链有一些看法。
简单来说,添加一个
!
意味着你 100% 保证给出一个值....如果你添加一个“!”并且不给出一个值应用程序将崩溃说 returned 一个值为 nil(或类似的东西)....
?
意味着您可能 return 一个值...如果您能提供帮助,这是更好的做事方式...
当我从Objective-C
转为Swift
编程时,我遇到了'!
'(感叹号)和'?
'(问号)通常必须紧跟在 property
、method
调用等之后。这些标记有什么用,如果我们不使用它们会怎样?
我在网上搜索了详尽的答案,但没有找到。所以我决定把我的答案放在这里,以防有人为此寻找明确的答案。
我还在下面的回答中包含了一个 link 与我的问题类似的问题,您可以在其中找到有关如何以及在何处使用这些标记(即“!”和“?”)的进一步解释。 ').我的问题和我的回答比 link.
中的类似问题更基本这些标记使用的术语是 Optional Chaining
。它们一般用于区分大小写,例如,a property
是否是,a method call
returns nil
.
Apple's language guide for Optional Chaining
中解释的一个例子很好地说明了它们的用途:
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
have an optional
residence
property of typeResidence
?.If you create a new
Person
instance, itsresidence
property is default initialized tonil
, by virtue of being optional. In the code below,john
has aresidence
property value ofnil
:let john = Person()
If you try to access the
numberOfRooms
property of this person’sresidence
, by placing an exclamation mark afterresidence
to force the unwrapping of its value, you trigger a runtime error, because there is noresidence
value to unwrap:let roomCount = john.residence!.numberOfRooms // this triggers a runtime error
The code above succeeds when
john.residence
has a non-nil value and will setroomCount
to anInt
value containing the appropriate number of rooms. However, this code always triggers a runtime error whenresidence
isnil
, 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."
This tells Swift to “chain” on the optional
residence
property and to retrieve the value ofnumberOfRooms
ifresidence
exists.Because the attempt to access
numberOfRooms
has the potential to fail, the optional chaining attempt returns a value of typeInt?
, or “optional Int”. Whenresidence
isnil
, as in the example above, this optionalInt
will also benil
, to reflect the fact that it was not possible to accessnumberOfRooms
. The optionalInt
is accessed through optional binding to unwrap the integer and assign the nonoptional value to theroomCount
variable.Note that this is true even though
numberOfRooms
is a nonoptionalInt
. The fact that it is queried through an optional chain means that the call tonumberOfRooms
will always return anInt?
instead of anInt
.You can assign a
Residence
instance tojohn.residence
, so that it no longer has anil
value:john.residence = Residence()
除了上面对可选链的一般概述之外,您还可以在 Whosebug 中查看此answer。
希望这能让您对可选链有一些看法。
简单来说,添加一个
!
意味着你 100% 保证给出一个值....如果你添加一个“!”并且不给出一个值应用程序将崩溃说 returned 一个值为 nil(或类似的东西)....
?
意味着您可能 return 一个值...如果您能提供帮助,这是更好的做事方式...