当参数化类继承自符合Equatable的另一个类时,==调用超类的==.任何人都可以解释为什么会发生这种情况和/或我在这里做错了什么?我相信一个最好的例子说明了我的问题:
public class Foo: Equatable {} public func ==(lhs: Foo,rhs: Foo) -> Bool { return false } //Parametrized public class Bar<T: Equatable>: Foo { public var bar: T? public init(barIn: T?) { self.bar = barIn } } public func ==<T>(lhs: Bar<T>,rhs: Bar<T>) -> Bool { return lhs.bar == rhs.bar } //Non parametrized public class Baz: Foo { public var baz: Int? public init(bazIn: Int?) { self.baz = bazIn } } public func ==(lhs: Baz,rhs: Baz) -> Bool { return lhs.baz == rhs.baz } //Parametrized,no inheritance public class Qux<T: Equatable>: Equatable { public var qux: T? public init(quxIn: T?) { self.qux = quxIn } } public func ==<T>(lhs: Qux<T>,rhs: Qux<T>) -> Bool { return lhs.qux == rhs.qux } Bar<Int>(barIn: 1) == Bar<Int>(barIn: 1) //false Baz(bazIn: 1) == Baz(bazIn: 1) //true Qux(quxIn: 1) == Qux(quxIn: 1) //true,of course
虽然我没有在Swift参考文献中找到任何关于此的内容,this gives us a clue:
Generics are lower down the pecking order. Remember,Swift likes to be as “specific” as possible,and generics are less specific. Functions with non-generic arguments (even ones that are protocols) are always preferred over generic ones:
但这似乎与Equatable没有任何关系;此测试向我们显示了相同的行为:
class Foo {}; class Bar<T>: Foo {}; class Baz: Bar<Int> {}; class Qux<T>: Baz {}; func test(foo: Foo) { print("Foo version!"); }; func test<T>(bar: Bar<T>) { print("Bar version!"); }; func test(baz: Baz) { print("Baz version!"); }; func test<T>(qux: Qux<T>) { print("Qux version!"); }; let foo = Foo(); let bar = Bar<Int>(); let baz = Baz(); let baz2: Bar<Int> = Baz(); let qux = Qux<Float>(); test(foo); // Foo test(bar); // Foo test(baz); // Baz test(baz2); // Foo test(qux); // Baz
所以这里发生的是当选择一个自由函数,同时使用它的静态类型而不是动态类型时,Swift不喜欢使用任何泛型,即使该泛型是一个类型参数,它确实应该是最专业的选择.
因此,似乎要解决这个问题,正如@VMAtm所建议的那样,你应该在类中添加一个像equalTo这样的方法,以便在运行时获取实际的方法.