4

根据 Apple 文档,可选链接如下:

如果可选值非零,则通过在希望调用属性、方法或下标的可选值后放置问号 (?) 来指定可选链接。...当可选项为 nil 时,可选项链接优雅地失败...

我对此的解释是,如下结构是可选链接:

someMasterObject.possiblyNilHandler?.handleTheSituation()

...并且如果处理程序不为零,上述行将调用 handleTheSituation 方法,如果处理程序为零,则优雅地失败(跳过行)。

然而,我看到的几乎所有可选链接示例都使用“if let”构造,如下所示:

if let handler = someMasterObject.possiblyNilHandler{
  handler.handleTheSituation()
}

事实上,我在网上找到的文档和示例大量使用了与可选链接相关的“if let”结构,看起来好像是可选链接。

但是,我是否正确假设我的第一个示例是支持使用可选链接,并且 if let 构造是使用(或密切相关)可选链接的另一种构造?

4

3 回答 3

11

可选链接在更多情况下有用,而不仅仅是可选绑定 ( 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
于 2015-01-01T21:39:09.707 回答
6

结论是正确的 -let是一个独立但有用的构造。在上下文中,它仅在 if-body 中引入绑定,并且仅当绑定值不是 nil 时才执行 if-body。(从技术上讲,它打开了一个可选的绑定。)

let不影响如何处理右侧的表达式(有或没有链接)。例如,如果someMasterObject是 optional/nil 它会失败而不是“链”——即使是let.

当一个或另一个(或两者)更“正确”取决于情况:例如。什么被链接以及应该采取什么纠正措施。


例如,如果someMasterObject可以为 nil,我们可能有以下同时使用链接和let. 还要注意返回值的重要性,而不是简单地丢弃或“失败时为零”:

if let handler = someMasterObject?.possiblyNilHandler{
  return handler.handleTheSituation()
} else {
  return FAILED_TO_CALL
}

然后将其与非等效链式形式进行比较,后者只会nil在调用失败的情况下返回,但 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
}
于 2015-01-01T21:05:55.743 回答
1

通过可选链接调用方法是完全可以的——你不需要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.")
}

链接到本书章节

请注意,nil即使示例中的函数没有返回值,检查也有效。由于使用可选链接在可选值上调用它,因此类型为Void?, not Void,这使得比较成为可能。

于 2015-01-01T21:08:04.290 回答