2017-10-10 269 views
0

以下代码用于在Swift 3.2中为我工作,但使用Swift 4的最新版本时,出现了一个我无法理解的奇怪错误。通用协议Swift 4错误

我试图创建一个通用的协议,像这样:

public protocol FactoryComponent { 
    associatedtype Argument 
    associatedtype Service 
    static var factory: (Resolver) -> (Argument) -> Service { get } 
} 

public extension FactoryComponent { 
    public typealias Factory = (Argument) -> Service 
} 

在这里使用它:

public extension Container { 
    @discardableResult 
    public func register<Component: FactoryComponent>(
    factory componentType: Component.Type 
) -> ServiceEntry<Component.Factory> { // On this line the error shows 
    return self.register(componentType.Factory.self) { resolver in 
     componentType.factory(resolver) 
    } 
    } 
} 

错误:

'组件' 没有一个成员类型命名为“工厂”;你的意思是'工厂'?

当然,自动修复没有帮助,因为错误是没用的......

我检查了斯威夫特4重大更改,并没有看到任何涉及通用协议。

可以somone请帮我理解这是什么意思?

+0

*自包含*示例将会有所帮助。 –

回答

0

似乎缺少一个FactoryComponent的具体类。 Factory类型别名只能由协议的具体类调用。

  1. 尝试创建一个实现其协议的FactoryComponent具体类
  2. ArgumentService您的实现仍然通用的,需要一个具体类型。我的英语很糟糕,但我希望我一直在帮助你。如果我的回答不清楚,请查看代码下面的代码。

```

class Resolver {} 

protocol FactoryComponent { 
    associatedtype Argument 
    associatedtype Service 
    static var factory: (Resolver) -> (Argument) -> Service { get } 
} 

extension FactoryComponent { 
    typealias Factory = (Argument) -> Service 
} 

class ConcreteFactoryComponent: FactoryComponent { 
    static var factory: (Resolver) -> Factory { 
    return foo 
    } 

    static func foo(_ resolver: Resolver) -> Factory { 
    let factory: Factory = { argument in return "" } 
    return factory 
    } 

    typealias Argument = String 
    typealias Service = String 
} 

let factory: ConcreteFactoryComponent.Factory = { argument in return "" } 

```

0

我相信错误是不是真的与返回类型的线。由于@escaping的新默认值,Swift 4中泛型签名解析的处理略有改变。这个函数调用一个与函数本身具有相同签名的self.register函数可能是问题的根源。

从其他类似的情况下,我会建议看一下Container.register的签名。如果碰巧有一个@escaping闭包,那么扩展中泛型函数的签名也应该有一个,以便它被识别为过载。

看到这个职位:https://stackoverflow.com/a/43081214/5237560

[编辑]我才意识到这种变化是迅速的2和3之间的情况下,它可以提供一些启示离开这里的答案。