【问题标题】:Swift optionals and equality operatorSwift 选项和相等运算符
【发布时间】:2016-09-20 16:05:24
【问题描述】:

查找有关此特定行为的文档引用或名称或链接,这类似于可选绑定,但在文档的那部分中未提及。

我可以使用 == 运算符测试一个可选项,并针对 nil 及其实际值进行测试,而无需进行任何显式展开:

var toggle: Bool? = nil
if (toggle == true || toggle == nil) {
    // do something
}

这会按照您的意愿编译和工作,但这里发生的情况是我不必明确解开toggle!== 已经为我安全地完成了。

这很方便,但我承认当我注意到它时有点惊讶。这只是默认== 实现的一种行为吗?或者这里发生了语言中的其他事情?感谢您的洞察力。

【问题讨论】:

  • 如果你命令点击==,你会看到有一个public func ==<T : Equatable>(lhs: T?, rhs: T?) -> Bool,它接受两个可选参数作为操作数。
  • 确实如此,但为什么要这样做呢?这是语言设计中的哲学吗?还是只是为了方便?还是我想太多了?
  • 我认为这很方便。在 Swift 3 中移除的带可选选项的比较运算符:github.com/apple/swift-evolution/blob/master/proposals/…。但是等式运算符仍然存在:“接受可选操作数的 == 和 != 的变体仍然有用,并且它们的结果并不令人惊讶,因此它们将保留。”
  • @MartinR。谢谢。该链接非常有用且有趣
  • @BradThomas:您使用的是哪个 Xcode 版本?比较stackoverflow.com/a/56870050/1187415

标签: swift operators optional


【解决方案1】:

Swift 有一个相等运算符接受两个可选值 (一个 Equatable 基类型):

public func ==<T : Equatable>(lhs: T?, rhs: T?) -> Bool

可以在Optional.swift找到实现:

public func == <T: Equatable>(lhs: T?, rhs: T?) -> Bool {
  switch (lhs, rhs) {
  case let (l?, r?):
    return l == r
  case (nil, nil):
    return true
  default:
    return false
  }
}

它做了人们所期望的:操作数相等,如果它们 都是nil,或者如果它们都不是nil 并且未包装 值相等。

类似的比较运算符 &lt; 等采用可选项已经 在 Swift 3 中删除,比较 SE-0121 Remove Optional Comparison Operators:

删除接受可选操作数的 和 >= 版本。

接受可选操作数的 == 和 != 的变体仍然有用,并且它们的结果并不令人惊讶,因此它们将保留。

所以这按预期工作:

let b: Bool? = nil
print(b == true) // prints "false"

但正如马特指出的,这不能通过隐式展开来完成 选项,这里左边的操作数将被解包:

let b: Bool! = nil
print(b == true) // crashes

【讨论】:

  • 警告:不要尝试使用隐式展开的 Optional。可怕的事情(tm)可能会发生。
  • @matt 在 swift 5.6 中什么也没发生。应用不会崩溃。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-05
  • 1970-01-01
  • 2014-08-21
  • 1970-01-01
相关资源
最近更新 更多