2017-10-10 5 views
0

Der folgende Code verwenden, um für mich bei Swift 3.2 zu arbeiten, aber mit der neuesten Version von Swift 4 bekomme ich einen seltsamen Fehler, den ich nicht verstehen kann.Generic Protokoll Swift 4 Fehler

Ich versuche, ein generisches Protokoll zu erstellen, wie so:

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

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

Und es hier mit:

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) 
    } 
    } 
} 

Fehler:

'Komponente' hat kein Mitglied Typen benannt "Fabrik"; meinst du "Fabrik"?

Und natürlich die Auto-fix hilft nicht, da der Fehler ist nutzlos ...

ich ausgecheckt Swift 4 Brechen Veränderungen und sehen etwas Einbeziehung generische Protokolle nicht.

Kann mir jemand bitte verstehen, was das bedeutet?

+0

Ein * eigenständiges * Beispiel wäre hilfreich. –

Antwort

0

Es scheint, dass eine konkrete Klasse von FactoryComponent fehlt. Der Aliasname Factory kann nur von den konkreten Klassen des Protokolls aufgerufen werden.

  1. versuchen, eine FactoryComponent konkrete Klasse erstellen, dessen Protokoll einen konkreten Typ und muss von der jeweiligen Implementierung implementiert
  2. Die Argument und Service noch generisch. Mein Englisch ist sehr schlecht, aber ich hoffe, ich habe dir geholfen. Überprüfen Sie den Code unten, wenn ich auf meiner Antwort nicht klar war.

`` `

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

Ich glaube, der Fehler nicht wirklich auf der Linie mit dem Rückgabetyp ist. Die Verarbeitung der generischen Signaturauflösung hat sich in Swift 4 aufgrund der neuen Standardeinstellung für @escaping leicht geändert. Die Tatsache, dass die Funktion eine self.register-Funktion mit einer identischen Signatur als Funktion selbst aufruft, ist wahrscheinlich die Ursache des Problems.

Aus anderen ähnlichen Fällen würde ich vorschlagen, die Signatur des Container.Register zu betrachten. Wenn es eine @ escaping-Schließung gibt, sollte die Signatur der generischen Funktion in der Erweiterung auch eine haben, so dass sie als eine Überladung erkannt wird.

Sehen Sie diesen Beitrag: https://stackoverflow.com/a/43081214/5237560

[EDIT] Ich habe gerade diese Änderung zwischen Swift 2 und 3. Verlassen Sie die Antwort hier im Falle war es Inspiration liefern kann.