泛型和专业化协议

时间:2019-03-13 17:48:02

标签: swift generics swift-protocols

是否有一种方法可以在协议中定义泛型函数,并允许符合条件的对象为该协议定义特殊化?例如:

protocol Generic {
    func generic<T>(prop: T, otherProp: String)
}

class Gen: Generic {
    func generic<T>(prop: T, otherProp: String) {
        print("generic")
    }

    func generic(prop: String, otherProp: String) {
        print(prop)
    }
}

现在,如果我像这样使用类:

let inst = Gen()
inst.generic(prop: 1, otherProp: "Go")
inst.generic(prop: "Hello", otherProp: "Stop")

我得到了预期的结果:

generic
Hello

但是,如果我声明inst的类型为Generic

let inst: Generic = Gen()
inst.generic(prop: 1, otherProp: "Go")
inst.generic(prop: "Hello", otherProp: "Stop")

我得到:

generic
generic

因此,如果我具有类型Generic的属性,则无法使用协议实现者对泛型函数的特殊化。这是预期的行为吗?有没有一种方法可以实现我要寻找的行为,即使用通用功能的特殊性,即使在通过协议接口访问时也是如此?我将不胜感激。谢谢大家。

2 个答案:

答案 0 :(得分:1)

如果您声明协议要求为通用函数,则不能通过协议类型调用同一函数的更专业的重载版本。但是,您可以通过检查通用输入参数的类型来专门为您的采用类实现通用功能。

class Gen: Generic {
    func generic<T>(prop: T, otherProp: String) {
        if prop is String {
            print(prop)
        } else {
            print("generic")
        }
    }
}

let inst: Generic = Gen()
inst.generic(prop: 1, otherProp: "Go")
inst.generic(prop: "Hello", otherProp: "Stop")

答案 1 :(得分:0)

您可以在协议中添加方法签名generic(String, String)并添加带有扩展名的默认实现:

protocol Generic {
    func generic<T>(prop: T, otherProp: String)
    func generic(prop: String, otherProp: String)
}

extension Generic {
    func generic(prop: String, otherProp: String) {
        generic(prop: prop as Any, otherProp: otherProp)
    }
}