如何使用泛型函数扩展类型创建协议

时间:2019-04-10 12:20:08

标签: swift generics protocols swift-protocols

我正在尝试使用具有泛型函数的协议,其中T不仅等于类型,还扩展了它。

class MainItem {}
class Item1: MainItem {}
class Item2: MainItem {}

protocol MyProtocol {
    func myFunc<T: MainItem>() -> T // T extends MainItem
}

class ClassA: MyProtocol {
    func myFunc() -> Item1 { // not MainItem
        return Item1()
    }
}

class ClassB: MyProtocol {
    func myFunc() -> Item2 { // not MainItem
        return Item2()
    }
}

但我收到此错误

  

类型“ ClassA”不符合协议“ MyProtocol”

因为Item1不等于MainItem(它将展开它)。您如何使它工作?

例如,在Java中,所有操作都可以使用抽象类完成:

abstract class MyProtocol {
    abstract <T extends MainItem> T myFunc()
}

1 个答案:

答案 0 :(得分:4)

使用泛型不是您需要的方法。当您在协议中声明泛型函数时,泛型类型参数将意味着该函数对满足泛型类型限制的所有类型均有效,但是对于所有符合类型的函数,其功能签名仍需保持完整。

您要寻找的是protocol with associated type。协议上的关联类型意味着一致性类型可以决定使用哪种具体类型来代替关联类型,因此允许您在不同的一致性类中使用不同的关联类型。

protocol MyProtocol {
    associatedtype MyType: MainItem
    func myFunc() -> MyType
}

class ClassA: MyProtocol {
    func myFunc() -> Item1 {
        return Item1()
    }
}

class ClassB: MyProtocol {
    func myFunc() -> Item2 {
        return Item2()
    }
}