Swift 2.0:如果参数化类继承自Equatable类,则它不会调用正确的==函数

Ken*_*bur 7 overloading class operator-overloading language-lawyer swift

当参数化类继承自另一个符合的类时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
Run Code Online (Sandbox Code Playgroud)

pau*_*ens 3

虽然我没有在 Swift 参考资料中找到任何与此相关的内容,但这给了我们一个线索

\n\n
\n

仿制药的地位较低。请记住,Swift 喜欢尽可能 \xe2\x80\x9cspecific\xe2\x80\x9d ,而泛型则不太具体。具有非泛型参数的函数(甚至是协议的函数)始终优于泛型函数:

\n
\n\n

但这似乎与 没有任何关系Equatable;这个测试向我们展示了相同的行为:

\n\n
class Foo {};\nclass Bar<T>: Foo {};\nclass Baz: Bar<Int> {};\nclass Qux<T>: Baz {};\n\nfunc test(foo: Foo) {\n    print("Foo version!");\n};\n\nfunc test<T>(bar: Bar<T>) {\n    print("Bar version!");\n};\n\nfunc test(baz: Baz) {\n    print("Baz version!");\n};\n\nfunc test<T>(qux: Qux<T>) {\n    print("Qux version!");\n};\n\nlet foo = Foo();\nlet bar = Bar<Int>();\nlet baz = Baz();\nlet baz2: Bar<Int> = Baz();\nlet qux = Qux<Float>();\n\ntest(foo);  // Foo\ntest(bar);  // Foo\ntest(baz);  // Baz\ntest(baz2); // Foo\ntest(qux);  // Baz\n
Run Code Online (Sandbox Code Playgroud)\n\n

所以这里发生的事情是,当选择一个自由函数时,除了使用其静态类型而不是动态类型之外,Swift 更喜欢不使用任何泛型,即使该泛型是类型参数并且实际上它应该是最专业的选择。

\n\n

因此,似乎要解决这个问题,正如 @VMAtm 所建议的,您应该equalTo向类中添加类似的方法,以便在运行时获取实际的方法。

\n