Swift 4:以协议为关联类型的通用协议的实现
Swift 4: Implementation of a generic protocol with protocol as an associated type
我在 Swift 3.1 到 Swift 4 代码库迁移期间遇到了问题。
当您尝试实现一个通用协议方法时,问题就出现了,该方法采用一个带有通用参数的闭包,并将一个协议作为关联类型。这比听起来容易:)
以下代码在 Swift 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) {
}
}
但是在 Swift 4 中,编译器给我一个关于 class Foo
不符合协议 FooType
并且缺少 foo(action:)
方法实现的错误。
顺便说一句 Xcode 9 "fix-it" 生成了与我相同的实现。
如果我使用 BarType
作为参数类型,代码可以编译,但丢失具体类型信息并不好。
结果是删除行
typealias BarType = Bar
问题已解决。这是公平的——类型推断完成了它的工作。
尽管如此,它应该是一个合法的代码,而且似乎是编译器中的一个错误。
Reported相应地。
我们应该使用 typealias 泛型变量来提供类型
协议的关联类型。我会在函数中使用 typealias 通用变量名。这更有意义也更合法,但我仍然不知道为什么编译器不知道闭包中的 typealias 参数。
class Foo: FooType {
typealias BarType = Bar
func foo(bar: BarType) {
/*Code*/
}
func foo(action: (BarType) -> Void) {
/*Code*/
}
}
我在 Swift 3.1 到 Swift 4 代码库迁移期间遇到了问题。
当您尝试实现一个通用协议方法时,问题就出现了,该方法采用一个带有通用参数的闭包,并将一个协议作为关联类型。这比听起来容易:)
以下代码在 Swift 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) {
}
}
但是在 Swift 4 中,编译器给我一个关于 class Foo
不符合协议 FooType
并且缺少 foo(action:)
方法实现的错误。
顺便说一句 Xcode 9 "fix-it" 生成了与我相同的实现。
如果我使用 BarType
作为参数类型,代码可以编译,但丢失具体类型信息并不好。
结果是删除行
typealias BarType = Bar
问题已解决。这是公平的——类型推断完成了它的工作。
尽管如此,它应该是一个合法的代码,而且似乎是编译器中的一个错误。
Reported相应地。
我们应该使用 typealias 泛型变量来提供类型 协议的关联类型。我会在函数中使用 typealias 通用变量名。这更有意义也更合法,但我仍然不知道为什么编译器不知道闭包中的 typealias 参数。
class Foo: FooType {
typealias BarType = Bar
func foo(bar: BarType) {
/*Code*/
}
func foo(action: (BarType) -> Void) {
/*Code*/
}
}