Swift 可选链接总是通过 if let 构造完成,还是仅使用带可选的问号完成?
Is Swift optional chaining always done with the if let construction, or is it just done using a question mark with an optional?
根据 Apple 文档,可选链接如下:
You specify optional chaining by placing a question mark (?) after the optional value on which you wish to call a property, method or subscript if the optional is non-nil. ... optional chaining fails gracefully when the optional is nil ...
我对此的解释是,如下所示的构造是可选链接:
someMasterObject.possiblyNilHandler?.handleTheSituation()
...如果处理程序不为零,上面的行将调用 handleTheSituation 方法,如果处理程序为零,则正常失败(跳过行)。
然而,我看到的几乎所有可选链接示例都使用 "if let" 结构,如:
if let handler = someMasterObject.possiblyNilHandler{
handler.handleTheSituation()
}
事实上,我在网上找到的文档和示例大量使用了与可选链接相关的 "if let" 结构,看起来好像是可选链接。
然而,假设我的第一个示例是支持使用可选链接并且 if let 构造是另一个使用(或密切相关)可选链接的构造,我是否正确?
结论是正确的 - let
是一个 独立的 但有用的结构。在上下文中,它仅在 if-body 中引入绑定,并且仅当绑定值不为 nil 时才执行 if-body。 (从技术上讲,它解开一个可选绑定。)
let
不影响右侧表达式(有或没有链接)的处理方式。例如,如果 someMasterObject
是 optional/nil 它将失败而不是 "chain" - 即使 let
.
当一个或另一个(或两者)更多时 "correct" 取决于情况:例如。链接的是什么以及应该采取什么纠正措施。
例如,如果 someMasterObject
可以为 nil,我们可能会有以下同时使用链接和 let
的代码。另请注意 return 值的重要性,而不是简单地丢弃或 "nil on failure":
if let handler = someMasterObject?.possiblyNilHandler{
return handler.handleTheSituation()
} else {
return FAILED_TO_CALL
}
然后将其与非等效链接形式进行比较,后者在调用失败的情况下只会return nil
,但没有可能是来自 handleTheSituation
!
的有效 return 值
return someMasterObject?.possiblyNilHandler?.handleTheSituation()
另一方面,请考虑总是将链接直接转换为嵌套的 if-let 语句:
result_of_expression = someMasterObject?.possiblyNilHandle?.handleTheSituation()
if let master = someMasterObject {
if let handler = master.possiblyNilHandler {
result_of_expression = handler.handleTheSituation()
} else {
result_of_expression = nil
}
} else {
result_of_expression = nil
}
通过可选链调用方法是完全正确的 - 你不需要 if
围绕它。如果在调用时可选值恰好是 nil
,您的代码将不会抛出异常。但是,您将无法查明该方法是否具有 运行。
但是,通常您希望在可选的链接方法调用周围放置一个 if
以检测该方法是否已被调用:
func printNumberOfRooms() {
println("The number of rooms is \(numberOfRooms)")
}
if john.residence?.printNumberOfRooms() != nil {
println("It was possible to print the number of rooms.")
} else {
println("It was not possible to print the number of rooms.")
}
请注意,即使示例中的函数没有 return 值,nil
检查仍然有效。由于它是使用可选链接在可选值上调用的,因此类型是 Void?
,而不是 Void
,这使得比较成为可能。
可选链接在更多情况下比仅可选绑定有用 (if let
):
person?.name = "Fred" // assign "Fred" to name property if person is not nil
person?.congratulate() // call congratulate method if person is not nil
let name = person?.name ?? "none" // nil coalescing operator
let age = dict?["age"] ?? 0 // subscripting an optional variable
if var name = person?.name { // optional binding using var instead of let
根据 Apple 文档,可选链接如下:
You specify optional chaining by placing a question mark (?) after the optional value on which you wish to call a property, method or subscript if the optional is non-nil. ... optional chaining fails gracefully when the optional is nil ...
我对此的解释是,如下所示的构造是可选链接:
someMasterObject.possiblyNilHandler?.handleTheSituation()
...如果处理程序不为零,上面的行将调用 handleTheSituation 方法,如果处理程序为零,则正常失败(跳过行)。
然而,我看到的几乎所有可选链接示例都使用 "if let" 结构,如:
if let handler = someMasterObject.possiblyNilHandler{
handler.handleTheSituation()
}
事实上,我在网上找到的文档和示例大量使用了与可选链接相关的 "if let" 结构,看起来好像是可选链接。
然而,假设我的第一个示例是支持使用可选链接并且 if let 构造是另一个使用(或密切相关)可选链接的构造,我是否正确?
结论是正确的 - let
是一个 独立的 但有用的结构。在上下文中,它仅在 if-body 中引入绑定,并且仅当绑定值不为 nil 时才执行 if-body。 (从技术上讲,它解开一个可选绑定。)
let
不影响右侧表达式(有或没有链接)的处理方式。例如,如果 someMasterObject
是 optional/nil 它将失败而不是 "chain" - 即使 let
.
当一个或另一个(或两者)更多时 "correct" 取决于情况:例如。链接的是什么以及应该采取什么纠正措施。
例如,如果 someMasterObject
可以为 nil,我们可能会有以下同时使用链接和 let
的代码。另请注意 return 值的重要性,而不是简单地丢弃或 "nil on failure":
if let handler = someMasterObject?.possiblyNilHandler{
return handler.handleTheSituation()
} else {
return FAILED_TO_CALL
}
然后将其与非等效链接形式进行比较,后者在调用失败的情况下只会return nil
,但没有可能是来自 handleTheSituation
!
return someMasterObject?.possiblyNilHandler?.handleTheSituation()
另一方面,请考虑总是将链接直接转换为嵌套的 if-let 语句:
result_of_expression = someMasterObject?.possiblyNilHandle?.handleTheSituation()
if let master = someMasterObject {
if let handler = master.possiblyNilHandler {
result_of_expression = handler.handleTheSituation()
} else {
result_of_expression = nil
}
} else {
result_of_expression = nil
}
通过可选链调用方法是完全正确的 - 你不需要 if
围绕它。如果在调用时可选值恰好是 nil
,您的代码将不会抛出异常。但是,您将无法查明该方法是否具有 运行。
但是,通常您希望在可选的链接方法调用周围放置一个 if
以检测该方法是否已被调用:
func printNumberOfRooms() {
println("The number of rooms is \(numberOfRooms)")
}
if john.residence?.printNumberOfRooms() != nil {
println("It was possible to print the number of rooms.")
} else {
println("It was not possible to print the number of rooms.")
}
请注意,即使示例中的函数没有 return 值,nil
检查仍然有效。由于它是使用可选链接在可选值上调用的,因此类型是 Void?
,而不是 Void
,这使得比较成为可能。
可选链接在更多情况下比仅可选绑定有用 (if let
):
person?.name = "Fred" // assign "Fred" to name property if person is not nil
person?.congratulate() // call congratulate method if person is not nil
let name = person?.name ?? "none" // nil coalescing operator
let age = dict?["age"] ?? 0 // subscripting an optional variable
if var name = person?.name { // optional binding using var instead of let