Swift 4:使用协议作为关联类型实现通用协议
问题描述:
在Swift 3.1到Swift 4代码库迁移过程中,我遇到了一个问题。Swift 4:使用协议作为关联类型实现通用协议
当您尝试实现一个通用协议方法,该协议方法将带有通用参数的闭包与协议作为关联类型相结合时,问题就会出现。它更容易比它的声音:)
下面的代码在雨燕3.1正常工作:
protocol FooType {
associatedtype BarType
func foo(bar: BarType)
func foo(action: (BarType) -> Void)
}
protocol Bar {}
class Foo: FooType {
typealias BarType = Bar
// Compiles in both 3.1 and 4
func foo(bar: Bar) {
}
// ERROR: Candidate has non-matching type (Bar) -> Void
func foo(action: (Bar) -> Void) {
}
}
但是在斯威夫特4编译器给了我有关类Foo
不符合协议FooType
与foo(action:)
方法实现丢失的错误。
顺便说一句Xcode 9“修复它”生成我有相同的实现。
如果我使用BarType
作为参数类型,代码将会编译,但不适用于删除具体类型信息。
答
答
我们应该使用typealias泛型变量来将类型提供给协议的 associatedType。我会去函数中使用typealias泛型变量名称。这使得更合理和合法,但我仍然不知道为什么编译器不知道闭包中的typealias参数。
class Foo: FooType {
typealias BarType = Bar
func foo(bar: BarType) {
/*Code*/
}
func foo(action: (BarType) -> Void) {
/*Code*/
}
}
这是合法的。但是,我们正在放弃关于在这个实现中与我们合作的具体类型的代码的清晰度。如果所有协议要求的实现提供了它正在使用的具体类型,类型推断甚至可以帮助我们不强制使用'typealias'声明。 您可以在相关类型部分查看它的[Apple解释](https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Generics.html)。 – chezzdev