2017-10-10 8 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破壊の変更をチェックアウトし、汎用的なプロトコルを含む何も表示されませんでした。

これは何を意味するのか理解してもらえますか?

+0

*自己完結型*の例が参考になります。 –

答えて

0

具体的なクラスはFactoryComponentです。 Factoryタイプのエイリアスは、プロトコルの具象クラスによってのみ呼び出すことができます。

  1. は、そのプロトコル実装上の
  2. Argument、まだServiceジェネリックを実装し、具体的なタイプを必要とFactoryComponent具象クラスを作成してみてください。私の英語はとても悪いですが、私はあなたを助けてくれることを願っています。私の答えではっきりしていない場合は、コードを確認してください。

`` `

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

私はエラーが戻り値の型を持つ行に本当にないと考えています。 @expingの新しいデフォルトのため、Swift 4では一般的な署名解決の処理がわずかに変更されました。関数が、関数自体と同じシグネチャでself.register関数を呼び出すということは、おそらく問題の原因です。

他の同様のインスタンスから、私はContainer.registerの署名を調べることをお勧めします。 @escapingクロージャがある場合は、拡張機能内のジェネリック関数のシグネチャにもオーバーロードとして認識されるシグネチャが必要です。

この記事を参照してください:https://stackoverflow.com/a/43081214/5237560

[EDIT]私はこの変更を実現し、ここで、それはいくつかのインスピレーションを提供することができた場合の答えを残しスウィフト2と3の間でした。

関連する問題