进一步限制Swift协议中的通用函数

时间:2014-12-03 02:33:02

标签: swift generics

我有一个像这样定义的Swift协议:

protocol MyProtocol {
    func genericMethod<T:MyProtocol>(param:T) -> ()
}

我可以在基类中实现泛型方法,如下所示:

class MyBaseClass : MyProtocol {
    func genericMethod<T where T:MyProtocol>(param:T) -> () {
        println("Performing generic method for type \(T.self)")
    }
}

class MySubClass : MyBaseClass {
    ...
}

到目前为止,这么好。我可以实现这个方法,它编译并运行得很好。

现在,我想做类似的事情,但在我的基类中,我希望通过要求它符合诸如Comparable之类的协议来进一步约束泛型方法的类型。我试试这个:

class MyBaseClass : MyProtocol {
    func genericMethod<T where T:MyProtocol, T:Comparable>(param:T) -> () {
        println("Performing generic method for type \(T.self)")
    }
}

在类型T上添加此附加约束后,类MyClass将无法编译,因为它不再符合协议。

似乎在泛型类型上添加额外约束不应导致它停止符合协议。我错过了什么?在我看来,协议是说genericMethod必须传递一个符合MyProtocol类型的参数。当我在MyBaseClass中实现这一点 - 只是MyProtocol的一个可能实现 - 我应该能够通过说参数myst符合Comparable 来进一步限制该实现除了 MyProtocol

有没有办法在基础实现中优化泛型类型,就像我在这里尝试做的那样?

2 个答案:

答案 0 :(得分:2)

在泛型类型上添加附加约束会导致它停止符合协议,因为协议应该保证一致性,并且不能保证非{{1的子类型的一致性}}。如果您希望所有Comparable个对象符合MyProtocol,那么您应该将其作为Comparable定义的一部分。

MyProtocol

我没有尝试过,但如果您将protocol MyProtocol: Comparable { //... } 设为MyBaseClass类型,它也可能有用。

答案 1 :(得分:0)

一种解决方案是采用另一种方式 - 将协议的通用版本定义为最限制性案例。这编译:

protocol P {
    func genericMethod<T where T:P, T:Comparable>(param:T) -> ()
}

class C1 : P {
    func genericMethod<T> (param:T) -> () {} // compiles even though omits Comparable
    func test() {
        genericMethod(C1()) // compiles even though C1 is not a Comparable
    }
}