2016-06-01 9 views
5

I generischen Protokolltyp als Funktion Rückgabetyp wie diese verwenden möchten: mit FehlernSwift Protokoll generic als Funktion Rückgabetyp

protocol P { 
    associatedtype T 
    func get() -> T? 
    func set(v: T) 
} 

class C<T>: P { 
    private var v: T? 
    func get() -> T? { 
    return v 
    } 
    func set(v: T) { 
    self.v = v 
    } 
} 

class Factory { 
    func createC<T>() -> P<T> { 
    return C<T>() 
    } 
} 

Aber diesem Code kompilieren klagte:

  1. Kann nicht nicht spezialisieren generischer Typ 'P'
  2. Rischer Parameter 'T' ist nicht in Funktion Signatur verwendet

Gibt es eine Möglichkeit, eine ähnliche Funktion mit Swift zu erreichen?

+0

Welche Linien haben die Fehler? Ich denke, ich habe eine gute Idee, wo # 2 ist, aber nicht # 1. – tktsubota

+0

@TroyT Die Zeile mit dem Code 'func createC () -> P {' – ufosky

Antwort

5

Das Problem ist, dass Sie die Syntax P<T> nicht verwenden können. P ist ein Protokoll, das heißt, es kann nicht als generischer Typ behandelt werden (Cannot specialize non-generic type 'P'), obwohl es eine gegebene associatedtype haben kann.

In der Tat, weil es eine associatedtype hat, können Sie jetzt nicht einmal den Protokolltyp selbst direkt verwenden - nur sie als generische Einschränkung nutzen können.

Die Lösung für Ihr Problem ist einfach die Funktionssignatur auf createC<T>() -> C<T> zu ändern, da genau das zurückgegeben wird!

class Factory { 
    func createC<T>() -> C<T> { 
     return C<T>() 
    } 
} 

Ich bin nicht ganz sicher, was Sie denken, Sie von der Möglichkeit, gewinnen würden hier einen Protokolltyp zurückzukehren. Wenn Ihr Code nur eine Vereinfachung darstellt und Sie eine beliebige Instanz zurückgeben möchten, die P entspricht, können Sie eine type erasure verwenden.

class AnyP<T> : P { 

    private let _get :() -> T? 
    private let _set : (T) ->() 

    init<U:P where U.T == T>(_ base:U) { 
     _get = base.get 
     _set = base.set 
    } 

    func get() -> T? {return _get()} 
    func set(v: T) {_set(v)} 
} 

class Factory { 
    func createC<T>() -> AnyP<T> { 
     return AnyP(C<T>()) 
    } 
}