我有一个协议我的 swift 代码库我有一个带有关联类型和两种方法的协议。这两种方法都为协议的关联类型定义了不同的通用约束。我想让结构符合两个协议,但有两种不同的关联类型。
protocol Convertable {
associatedtype TargetType
func convert() -> TargetType
}
func show<T : Convertable where T.TargetType == String>(toShow : T) {
print(toShow.convert())
}
func add<T : Convertable where T.TargetType == Int>(a : T, b : T) -> Int {
return a.convert() + b.convert()
}
struct MyData {
var data : Int
}
作为扩展,我使结构符合TargetType
将要使用的协议,String
以便将其传递给 show 方法:
extension MyData : Convertable {
func convert() -> String { return String(self.data) }
}
到目前为止,一切都按预期工作。但是现在我也希望结构体在绑定到 IntConvertable
时符合协议。TargetType
这似乎是不可能的?
我尝试的第一件事是将 convert 方法的第二个定义添加到扩展中:
extension MyData : Convertable {
func convert() -> String { return String(self.data) }
func convert() -> Int { return data }
}
编译器现在抱怨MyData
不再符合协议。其次是将其拆分为两个扩展并显式绑定 TargetType。
extension MyData : Convertable {
typealias TargetType = Int
func convert() -> Int { return data }
}
extension MyData : Convertable {
typealias TargetType = String
func convert() -> String { return String(data) }
}
这具有编译器现在抱怨 theTargetType
被重新定义的效果。
我最后一次尝试是定义两个扩展Convertable
协议并约束它们的协议TargetType
,然后通过扩展实现它们:
protocol ConvertableString : Convertable {
associatedtype TargetType = String
}
protocol ConvertableInt : Convertable {
associatedtype TargetType = Int
}
extension MyData : ConvertableInt {
func convert() -> Int { return self.data }
}
extension MyData : ConvertableString {
func convert() -> String { return String(self.data) }
}
这现在使编译器对扩展感到高兴,但不再对调用感到高兴,show
因为它不知道它可以使用MyData
.
有没有我监督过的事情,或者这目前是不可能的?