3

我在 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 编译器中,我给出了一个关于类Foo不符合协议FooTypefoo(action:)缺少方法实现的错误。

顺便说一句,Xcode 9“修复它”生成了与我相同的实现。

如果我BarType用作参数类型,则代码会编译,但丢失具体类型信息并不好。

4

2 回答 2

3

原来,删除线

typealias BarType = Bar

解决了这个问题。这是公平的 - 类型推理完成了它的工作。

尽管如此,它应该是合法的代码,并且看起来像是编译器中的错误。

据报

于 2017-06-08T18:10:30.537 回答
0

我们应该使用 typealias 泛型变量将类型提供给协议的 associatedType。我会在函数中使用 typealias 通用变量名。这更有意义和合法,但我仍然不知道为什么编译器不知道闭包中的 typealias 参数。

class Foo: FooType {
    typealias BarType = Bar


    func foo(bar: BarType) {
     /*Code*/
    }


    func foo(action: (BarType) -> Void) {
      /*Code*/
    }
}
于 2017-06-09T10:58:51.073 回答