最优雅的方式来比较Swift中的两个选项

dev*_*os1 15 optional swift

我有两个AnyObject?变量,我想比较参考相等性:

var oldValue: AnyObject?
var newValue: AnyObject?
...
if oldValue != newValue {
    changed = true
}
Run Code Online (Sandbox Code Playgroud)

这不起作用,因为我显然无法直接比较两个选项.我想要的行为好像我id在Objective-C 中比较s,即:

  • true 如果两者都是 nil
  • true 如果两者都有值且值也相等
  • false 除此以外

有没有一种优雅的方式在Swift中编写它(理想情况下无需编写自定义扩展)?

这是我提出的最好的:

if !(oldValue != nil && newValue != nil && oldValue == newValue)
Run Code Online (Sandbox Code Playgroud)

不是很漂亮 :(

sba*_*row 12

您可以使用 !==

来自Swift编程语言

Swift还提供了两个身份运算符(===!==),您可以使用它们来测试两个对象引用,它们都引用同一个对象实例.

一些好的例子和解释也在==和===之间

在@PEEJWEEJ点上,执行以下操作将导致 false

var newValue: AnyObject? = "String"
var oldValue: AnyObject? = "String"

if newValue === oldValue {
   print("true")
} else {
   print("false")
}
Run Code Online (Sandbox Code Playgroud)

  • 仅供参考,我认为如果oldValue和newValue是对象,则===将始终为false,除非它们实际上设置为同一个对象. (6认同)

Str*_*ers 11

假设您正在使用Comparable实体,这将适用于任何事情:

func optionalsAreEqual<T: Comparable>(firstVal: T?, secondVal: T?) -> Bool{

    if let firstVal = firstVal, secondVal = secondVal {
        return firstVal == secondVal
    }
    else{
        return firstVal == nil && secondVal == nil
   }
}
Run Code Online (Sandbox Code Playgroud)

它并不完全短小,但它具有表现力,清晰和​​可重复使用.


Nit*_*rad 7

我喜欢@Keith 的解决方案。但我认为它不是用 Swift 4 编写的,因为我无法用 Swift 4 编译器编译它。

所以我在这里将他的代码转换为 Swift 4 版本。

请记住,如果您使用的 Swift 语言版本高于Swift 4.1,则不需要此答案,因为它默认提供此功能。您可以参考此处了解更多详情。

@Keith 代码的 Swift 4 版本:

infix operator ==? : ComparisonPrecedence

func ==? <T: Comparable>(lhs: T?, rhs: T?) -> Bool {
    if let lhs = lhs, let rhs = rhs {
        return lhs == rhs
    } else {
        return lhs == nil && rhs == nil
    }
}

func ==? <T: AnyObject>(lhs: T?, rhs: T?) -> Bool {
    if let lhs = lhs, let rhs = rhs {
        return lhs === rhs
    } else {
        return lhs == nil && rhs == nil
    }
}
Run Code Online (Sandbox Code Playgroud)