我有一个协议我的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
,以便将其传递给显示方法:
extension MyData : Convertable {
func convert() -> String { return String(self.data) }
}
到目前为止一切正常。但是现在我还希望在TargetType
绑定到Int时使结构符合Convertable
协议。这似乎是不可能的?
我想的第一件事就是到转换方法的第二个定义添加到扩展:
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) }
}
这有编译器现在抱怨的了TargetType
被重新定义的效果。
我最后的尝试是定义扩展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
调用该功能。
有没有我监督过的一些事情,或者这是目前不可能在迅速?
在我看来,这不仅是不可能的,而且几乎是不可能的。你已经用_one single_关联类型声明了一个协议。如何将它设置为同一类型的两种不同类型? – werediver
这不是同一个协议,因为协议在TargetType上是通用的,所以协议的变体与TargetType一样多。与协议类型相关的整个想法是,您可以通过它们的关联类型进行区分。如果你看看C#,那么可以实现绑定到泛型参数的不同类型的相同接口。 – Kolja
嗯,这不是C#,你不应该这样想,因为那不起作用。 – werediver