在Swift中比较两个自定义对象

3

我有以下在Swift中定义的协议:

protocol RecordingObserver {
    func aFunc()
}

我需要比较两个实现了这个协议的对象,以检查它们是否相同。我面临的问题是,显然Swift不允许我们这样做:

func areEqual(a:RecordingObserver,b:RecordingObserver){
    if a === b {
        println("Equal")
    }
}

有什么想法为什么会出现这种情况?我该如何用其他方法做到这一点?

你已经发布了一些代码;你能告诉我们你遇到的错误/意外行为吗?在“为什么会发生这种情况?”中,“this”是什么? - waldrumpus
@waldrumpus 他的代码 a === b 没有返回正确的值(即它们相等)。 - user470763
@kmcgrady 可能吧,但我认为如果提问者提供更多信息,这个问题会变得更好。 - waldrumpus
@waldrumpus 我想你是对的。虽然我们可以很容易地猜测发帖人在问什么,但如果问题能够更加明确清晰,那就更好了。 - user470763
你需要更清楚地表达你想做什么。你是想查看a和b是否都包含完全相同的对象(不是具有相同值的对象,而是同一个对象实例吗?)如果是这样,为什么不直接使用===运算符呢?那就是它的作用。如果不是,你需要让RecordingObserver协议也符合Equitable协议。然后对于所有符合RecordingObserver的对象,你需要实现==运算符。 - Duncan C
完成后,您将能够直接使用“==”比较任意2个RecordingObserver对象,而无需创建自己的“areEqual”方法。 - Duncan C
4个回答

4

=== 是“恒等于”运算符,用于测试两个对象引用是否都引用同一对象实例。它只能应用于引用类型(即 class 的实例)。

=== 与“等于”运算符 == 不同(Equatable 协议中需要使用“等于”运算符)。

因此,假设:

  • 实际的观察器是 class 的实例,且
  • 你的意图是检查 ab 是否引用同一实例,

那么,你必须将协议定义为 类协议

protocol RecordingObserver : class {
    // ...
}

那么,
func areEqual(a:RecordingObserver,b:RecordingObserver){
    if a === b {
        println("a and b refer to the same object instance")
    }
}

编译(并按预期工作)的原因是编译器知道ab是引用类型。


3

1
Equatable 确保类型实现了 ==,而不是 ===,因此这并不能解决编译器错误。(当然,我们还不知道 OP 是否真正需要 ===。) - Martin R

1
我相信NSObject类中有一个'isEqual'方法。如果你的自定义对象都是从这个类继承而来的,你应该能够比较a.isEqual(b)。

0

这是因为你说你的对象只实现了RecordingObserver。所以编译器不知道是否可以比较它们。

试试这个:

func areEqual<T where T: Equatable, T: RecordingObserver>(a: T,b: T) {

}

您可以将此代码复制到单视图项目中进行测试:

protocol RecordingObserver {

}

class SomeClass: NSObject, RecordingObserver {
}

class ViewController: UIViewController {

    func areEqual<T where T: Equatable, T: RecordingObserver>(a: T,b: T) -> Bool {
        return true
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        let a = SomeClass()
        let b = SomeClass()

        NSLog("\(areEqual(a, b: b))")
    }

}

除非RecordingObserver协议符合Equitable协议,否则这也行不通。 - Duncan C

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接