我一直在尝试实现一个协议和协议扩展,它在swift中提供了一个默认的==方法。像这样:
protocol NameProtocol: Equatable {
func getName() -> String
}
extension NameProtocol{}
func ==<T: NameProtocol>(lhs: T, rhs: T) -> Bool{
return lhs.getName() == rhs.getName()
}
然后是这样的一个类:
class NamedObject: NSObject, NameProtocol {
let name: String
init(name: String) {
self.name = name
super.init()
}
func getName() -> String {
return self.name
}
}
但是,永远不会调用自定义==方法:
let one = NamedObject(name: "Name")
let two = NamedObject(name: "Name")
if one == two {
NSLog("EQUAL")
}
else{
NSLog("NOT EQUAL")
}
我在这里做错了吗?
更新:
从我得到的答案看起来我想要完成的事情是不可能的。接近的唯一方法是子类(它有明显的缺点)。我要留意一个合适的解决方案。
答案 0 :(得分:2)
因为超类中的==
运算符优先于协议的运算符。对于NSObject
,==
表示指针相等。
如果从NSObject
删除继承,它将按预期工作:
class NamedObject: NameProtocol {
let name: String
init(name: String) {
self.name = name
super.init()
}
func getName() -> String {
return self.name
}
}
当==
有多个实现时,我无法找到有关优先顺序的任何文档。这只是我的经验。
编辑,而不是为协议定义==
,定义您自己的基类来覆盖NSObject
的默认行为:
class MyBaseClass: NSObject {
func getName() -> String {
fatalError("You must override this method")
}
}
func == (lhs: MyBaseClass, rhs: MyBaseClass) -> Bool {
return lhs.getName() == rhs.getName()
}
class NamedObject: MyBaseClass {
let name: String
init(name: String) {
self.name = name
}
override func getName() -> String {
return self.name
}
}
答案 1 :(得分:0)
您的类派生自NSObject。您重写isEqual:
(不是Swift ==
)来更改NSObject派生类对实例相等意味着什么的想法。
然而,将此移至协议扩展的策略永远不会起作用,因为Objective-C对Swift协议扩展一无所知。位于协议扩展中的代码对于Objective-C是完全不可见的。
所以,基本上,通过使这个类派生自NSObject,你已经在脚中拍摄了你的协议扩展策略。