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*/
    }
}