【问题标题】:Call priority of type-constrained generic functions in swift?swift中类型约束的泛型函数的调用优先级?
【发布时间】:2020-12-13 16:05:24
【问题描述】:

我有定义:

    func compare<T>(lhs: T, rhs: T) -> Bool where T: Equatable {
        return lhs == rhs
    }
    
    func compare<T>(lhs: T, rhs: T) -> Bool where T: AnyObject {
        return lhs === rhs
    }
    
    func compare<T>(lhs: T, rhs: T) -> Bool {
        return false
    }

当我在也符合Equatable 的引用类型对象上调用compare 时,编译器如何决定调用这些函数中的哪一个?

一个完全被接受的答案是官方 swift manifesto 的链接,解释了优先级是如何完成的,特别是当泛型符合两个都有专门化的不同协议时

【问题讨论】:

  • 你为什么不打电话给compare,看看是哪一个被叫了?
  • 如果对象是一个类,Equatable 的优先级可能高于AnyObject,而AnyObject 的优先级高于泛型。我认为您在那里的顺序正是您期望的优先级。
  • 这篇博文中的更多信息:airspeedvelocity.net/2014/10/26/…... 一般的经验法则是更具体的重载优先
  • @NewDev,但不清楚AnyObjectEquatable是否更具体,因为非对象类型也可以符合Equatable,这意味着它们的集合差异不为空(即也就是说,两者都不是另一个的子集)
  • @WinstonDu, Equatable 被认为比AnyObject 更具体。可能是因为与AnyObject 的一致性是隐含的......重点是这是在编译时确定的,并且由于有时很难看到差异,因此最好小心,不要滥用超载

标签: swift generics swift5


【解决方案1】:

无论出于何种原因,它对编译器来说都不是模棱两可的(我认为这是一个错误;关于我所期望的错误,请参见下文),但它对我们来说是。所以写一个重载来澄清行为!

func compare<T: AnyObject>(lhs: T, rhs: T) -> Bool {
  lhs === rhs
}

func compare<T: AnyObject & Equatable>(lhs: T, rhs: T) -> Bool {
  compare(lhs: lhs as AnyObject, rhs: rhs)
}

func compare<T: Equatable>(lhs: T, rhs: T) -> Bool {
  lhs == rhs
}

func compare<T>(lhs: T, rhs: T) -> Bool {
  false
}
protocol ModuleName_A { }
protocol ModuleName_B { }

func ƒ<A: ModuleName_A>(_: A) { }
func ƒ<B: ModuleName_B>(_: B) { }

struct S: ModuleName_A & ModuleName_B { }

ƒ(S()) // Ambiguous use of 'ƒ'

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多