Swift 2.0中equals运算符和NSObjects的错误? [英] Bug with equals operator and NSObjects in Swift 2.0?
问题描述
好吧,像这样在Swift 2.0中为NSObject子类编写自己的equals运算符时,会发生一些奇怪的事情:
Ok, something strange is happening when writing your own equals operator for NSObject subclasses in Swift 2.0 like this:
func ==(lhs: MyObject, rhs: MyObject) -> Bool {
return lhs.identifier == rhs.identifier
}
对于一个看起来像这样的类:
For a class that looks like this:
class MyObject: NSObject {
let identifier: String
init(identifier: String) {
self.identifier = identifier
}
}
这过去在Swift 1.2及更低版本中都可以正常工作.还是可以的:
This used to work just fine in Swift 1.2 and below. It still kind of works:
let myObject1 = MyObject(identifier: "A")
let myObject2 = MyObject(identifier: "A")
let result = (myObject1 == myObject2)
// result is true
到目前为止还不错,但是如果两个变量都是可选的呢?
So far so good, but what if both of the variables were optionals?
let myObject1: MyObject? = MyObject(identifier: "A")
let myObject2: MyObject? = MyObject(identifier: "A")
let result = (myObject1 == myObject2)
// result is false, equals operator was never even called
另一件事不再起作用:
let myObject1 = MyObject(identifier: "A")
let myObject2 = MyObject(identifier: "A")
let result = (myObject1 == myObject2)
// result is true
let result = (myObject1 != myObject2)
// result is true, equals operator was never even called
显然,!=不再调用==运算符并将其取反.似乎只是在比较实例时使用!=
So apparently, != no longer calls the == operator and negates it. It seems to just compare the instances instead when using !=
仅当您的类是NSObject的子类(直接或间接)时,才会发生所有这些情况.否则,一切都会如您所愿.
All of this only happens when your class is a subclass of NSObject (directly or indirectly). When it's not, everything works just like you would expect.
有人能告诉我这是Swift 2.0的新功能还是讨厌的错误?
Can anyone tell me if this is a new 'feature' in Swift 2.0 or just a nasty bug?
推荐答案
不幸的是,我不知道这是否被视为功能(我不这么认为).如果任何类的子类都符合Equatable
的类(例如NSObject
;它会比较实际实例),则会出现此问题.因此,如果您仅覆盖"子类的==
运算符,则所有其他运算符都像这样:
Unfortunately I don't know whether this is considered a feature or not (I don't think so). This problem occurs if any class subclasses a class which conforms to Equatable
(like NSObject
; it compares actual instances). So if you only "override" the ==
operator of the subclass all other operators like:
func !=<T : Equatable>(lhs: T, rhs: T) -> Bool
func ==<T : Equatable>(lhs: T?, rhs: T?) -> Bool
func ==<T : Equatable>(lhs: [T], rhs: [T]) -> Bool
其中T
被限制为Equatable
,Swift使用基类的==
运算符.作为(耗时的)解决方法,您可以像这样重载所有必须使用的相等运算符:
where T
is constrained to be Equatable
Swift uses the ==
operator of the baseclass. As (time-consuming) workaround you can overload all the equality operators you have to use like so:
func !=(lhs: MyObject, rhs: MyObject) -> Bool { ... }
func ==(lhs: MyObject?, rhs: MyObject?) -> Bool { ... }
func ==(lhs: [MyObject], rhs: [MyObject]) -> Bool { ... }
原因
此行为的原因是,如果子类符合Equatable
,则将自我需求的Self
确定为此类.因此,每次使用符合Equatable
的(通用)类型调用==
时,它只会调用初始符合类的运算符.
The reason for this behavior is that if a subclass conforms to Equatable
the Self
of the self requirement is determined to be this class. So every time the ==
is called with a (generic) type that conforms to Equatable
it only calls the operator of the initial conforming class.
这篇关于Swift 2.0中equals运算符和NSObjects的错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!