2017-10-10 278 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之間的情況下,它可以提供一些啓示離開這裏的答案。