加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

发布时间:2020-12-14 05:23:51 所属栏目:百科 来源:网络整理
导读:当参数化类继承自符合Equatable的另一个类时,==调用超类的==.任何人都可以解释为什么会发生这种情况和/或我在这里做错了什么?我相信一个最好的例子说明了我的问题: public class Foo: Equatable {}public func ==(lhs: Foo,rhs: Foo) - Bool { return fals
当参数化类继承自符合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这样的方法,以便在运行时获取实际的方法.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读