我有两个AnyObject?
变量,我想比较参考相等:
var oldValue: AnyObject?
var newValue: AnyObject?
...
if oldValue != newValue {
changed = true
}
但这并不起作用,因为我显然无法直接比较两个选项。我希望这种行为好像我在Objective-C中比较id
,即:
true
如果两者都是nil
true
如果两者都有值且值也相等false
否则有没有一种优雅的方式在Swift中编写它(理想情况下无需编写自定义扩展)?
这是我提出的最佳选择:
if !(oldValue != nil && newValue != nil && oldValue == newValue)
不太漂亮。 :(
答案 0 :(得分:11)
假设您正在使用可比实体,这将适用于任何事情:
func optionalsAreEqual<T: Comparable>(firstVal: T?, secondVal: T?) -> Bool{
if let firstVal = firstVal, secondVal = secondVal {
return firstVal == secondVal
}
else{
return firstVal == nil && secondVal == nil
}
}
它不是短暂而甜蜜的,但它具有表现力,清晰和可重复使用。
答案 1 :(得分:11)
您可以使用!==
来自 Swift编程语言
Swift还提供了两个身份运算符(
===
和!==
),您可以使用它们测试两个对象引用是否同时引用同一个对象实例。
一些很好的例子和解释也在Difference between == and ===
在@PEEJWEEJ点上,执行以下操作将导致false
var newValue: AnyObject? = "String"
var oldValue: AnyObject? = "String"
if newValue === oldValue {
print("true")
} else {
print("false")
}
答案 2 :(得分:4)
我喜欢@Keith's解决方案。但我认为它不是用Swift 4编写的,因为我无法用Swift 4编译器编译它。
所以我在这里将他的代码转换为Swift 4版本。
请注意,如果您使用的是Swift语言的版本高于 Swift 4.1 ,则此答案无需,因为它默认提供此功能。您可以参考here了解更多详情。
@ 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
}
}
答案 3 :(得分:3)
我定义了一个自定义中缀运算符,它具有引用类型和值类型的函数。
func ==? <T: Comparable>(lhs: T?, rhs: T?) -> Bool {
if let lhs = lhs, rhs = rhs {
return lhs == rhs
} else{ return lhs == nil && rhs == nil }
}
func ==? <T: AnyObject>(lhs: T?, rhs: T?) -> Bool {
if let lhs = lhs, rhs = rhs {
return lhs === rhs
} else{ return lhs == nil && rhs == nil }
}
infix operator ==? { associativity left precedence 130 }
var aString: String? = nil
var bString: String? = nil
print(aString ==? bString) // true
aString = "test"
bString = "test"
print(aString ==? bString) // true
aString = "test2"
bString = "test"
print(aString ==? bString) // false
aString = "test"
bString = nil
print(aString ==? bString) // false
class TT {}
let x = TT()
var aClass: TT? = TT()
var bClass: TT? = TT()
print(aClass ==? bClass) // false
aClass = TT()
bClass = nil
print(aClass ==? bClass) // false
aClass = nil
bClass = nil
print(aClass ==? bClass) // true
aClass = x
bClass = x
print(aClass ==? bClass) // true
答案 4 :(得分:0)
对于某些==
类型,您可以重载Comparable
运算符
public func ==<T: SomeType>(lhs: T?, rhs: T?) -> Bool {
switch (lhs,rhs) {
case (.some(let lhs), .some(let rhs)):
return lhs == rhs
case (.none, .none):
return true
default:
return false
}
}
或者将===
用于AnyObject
的比较,但就我个人而言,我不希望一开始就使用AnyObject
。