【问题标题】:Can I use Optional chaining to give a default value for the property of an optional?我可以使用可选链接为可选属性提供默认值吗?
【发布时间】:2018-01-03 07:00:57
【问题描述】:

是否可以像这样同时使用可选链接和 nil 合并?

print("Meeting host: " + meeting.host?.email ?? “No host”)

我想这样做,但我收到一条错误消息,提示我的 String?没有打开。 email 是非可选字符串。

这是否可能,而不必事先打开 host,如果不是,为什么我这样做的尝试不起作用?

【问题讨论】:

  • 如果您收到“意外”编译器错误,请将表达式分成更小的部分。在你的情况下:从 let host = meeting.host?.email ?? "No host" ; print("Meeting host: " + host) 开始——你会注意到它可以编译,所以可选的链接和 nil-coalescing 可以正常工作。

标签: swift optional optional-chaining


【解决方案1】:

有一个更简单的解决方案:

class Host {
    var email: String?
}

var host: Host? = nil
print("Meeting host: " + String(describing: host?.email))

输出是:

会议主持人:无

【讨论】:

  • 这不做同样的事情。 host 是可选的,所以 host.email 不会编译。
  • 但是对于非零值,这将显示Meeting host: Optional(Bob) 或类似的东西,对吧?
【解决方案2】:

您不必打开它就可以使用它。这不是发生错误的原因。毕竟?? 就是为处理此类情况而设计的。

由于运算符优先级而发生错误。编译器认为它应该首先评估+,连接两个字符串,然后进行零合并。它看到第二个操作数没有被解包并抱怨。

要使其产生预期的结果,请通过添加括号明确告诉编译器首先评估??

print("Meeting host: " + (meeting.host?.email ?? “No host”))

【讨论】:

  • 请注意,以这种方式使用+ 会增加编译时间。强烈避免+带字符串;这是“我的 Swift 编译时间过长”问题的第一大原因。一个很好,但即使是两个或三个也会导致指数级问题。养成字符串插值的习惯:print("Meeting host: \(meeting.host?.email ?? "No host")") 这也正好摆脱了 Sweeper 解释得很好的优先级问题。
  • print() 接受可变数量的参数,所以也可以写成print("Meeting host:", meeting.host?.email ?? "No host")
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-06-19
  • 1970-01-01
  • 2011-01-11
  • 2017-09-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多