我正在尝试对泛型类进行扩展,该泛型类受泛型类型的约束。这是我认为应该工作的代码的简化:
struct Thing<T> {
var value: T
}
struct ContainsStringThing {
var stringThing: Thing<String>
}
extension Thing where T == String { // <-- Error location
func containedStringThing() -> ContainsStringThing {
return ContainsStringThing(stringThing: value)
}
}
但是,我收到以下错误消息:
相同类型的要求使得通用参数&#39; T&#39;非通用
我搜索了一种修复此问题的方法,并找到了使用协议约束扩展名而不是类型link to article的建议。完成后我最终得到了这个:
protocol StringProtocol { }
struct Thing<T> {
var value: T
}
struct ContainsStringThing {
var stringThing: Thing<StringProtocol>
}
extension Thing where T: StringProtocol {
func containedStringThing() -> ContainsStringThing {
return ContainsStringThing(stringThing: self) // <-- Error location
}
}
现在它确实让我限制了扩展名,但它显示了一条不同的错误消息:
无法转换类型的值&#39; Thing&lt; T&gt;&#39;预期参数类型&#39; Thing&lt; StringProtocol&gt;&#39;
现在它基本上知道T
本身符合协议StringProtocol
,但在引用整个对象Thing<T>
时它并不知道。
是否有任何解决方法,或者我应该将其作为进化提案提交给swift邮件列表?
注意:所有代码都在操场上进行测试,您只需复制并粘贴即可试用。
答案 0 :(得分:0)
作为一种解决方法,您可以使用self中的值创建Thing的新实例。
extension Thing where T: StringProtocol {
func containedStringThing() -> ContainsStringThing {
return ContainsStringThing(stringThing: Thing<StringProtocol>(value: self.value))
}
}
在Swift 2.2中,这样的扩展约束意味着 containedStringThing()函数将可用于其值类型符合StringProtocol的Thing。
如果Swift编译器可以将 self.value 的类型推断为 StringProtocol ,那就太好了。在这种情况下你可以写
ContainsStringThing(stringThing: self)
代替
ContainsStringThing(stringThing: Thing<StringProtocol>(value: self.value))
。你一定要填写提案。