2015-03-10 3 views
12

Da wir ein Swift-Protokoll mit einer static Methode haben:Reine Swift-Klasse-Protokoll mit statischer Methode konforme - Ausgabe mit Upcasting

protocol Creatable: class { 
    static func create() -> AnyObject 
} 

und eine reine Swift-Klasse, die das Protokoll entspricht:

class Foo : Creatable { 
    static func create() -> AnyObject { 
     return Foo() as AnyObject 
    } 
} 

Später, wenn man versucht, die Verwendung dieses Protokolls durch den Einsatz auf Typ Creatable zB zu machen:

var f : Creatable = Foo.self 
f.create() 

Der Compiler beschwert sich mit den folgenden:

error: type 'Foo.Type' does not conform to protocol 'Creatable' 

Die Frage ist: ist dies eine Einschränkung Swift oder ich die Protokolle und statische/Klassenmethode in die falsche Art und Weise verwendet wird. selbst

Class someClass = [Foo class]; 
if ([someClass conformsToProtocol:@protocol(Creatable)]) { 
    [(Class <Foo>)someClass create]; 
} 
+0

Zuerst habe ich über die statische Funktion in einer Klasse fragen, .. 'static' ist eigentlich für' struct's und 'CLASS' für‚statische‘Klassenfunktionen – borchero

+0

@OliverBorchert: in schnellen 1.2 Wir haben _real_ statische, einschließlich gespeicherter Eigenschaften – Antonio

+0

Oh, ich habe noch nicht realisiert, danke für den Hinweis^_^ – borchero

Antwort

9

A Creatable Referenzpunkte auf einer Instanz von Foo, nicht auf den Typ Foo:

Objective-C äquivalent wäre etwas ähnliches sein.

Um das Äquivalent der Klasse-Level-Protokoll-Implementierung zu erhalten, müssen Sie eine Instanz von Creatable.Type:

let c: Creatable.Type = Foo.self 

jedoch eine Fehlermeldung angezeigt werden, wenn Sie dann versuchen, es zu benutzen:

// error: accessing members of protocol type value 'Creatable.Type' is unimplemented 
c.create() 

All das gesagt, gibt es einen Grund, warum Sie nicht einfach Funktionen verwenden können, um Ihre Anforderung anstelle von Metatypen zu erfüllen?

let f = Foo.create 
// f is now a function,()->AnyObject, that creates Foos 
let someFoo = f() 
+0

Danke für Ihre Antwort. Der Grund, warum ich versuche, mit Metatypen zu arbeiten, ist, dass ich an einer Fabrik von Objekten arbeite. Im Idealfall würde ich eine neue Instanz aus dem Typ selbst erstellen. Aber wie ich fand, ist das mit der starken Typisierungsarchitektur von Swift nicht möglich. Als Workaround habe ich überlegt, das Protokoll mit dem statischen Methodenansatz zu verwenden. Auf diese Weise konnte ich Metatypen sammeln, die dem Protokoll entsprechen und Objekte erstellen. Vielleicht irre ich mich und es gibt eine bessere Art, Fabrik zu schaffen. –

+0

"Idealerweise würde ich eine neue Instanz aus dem Typ selbst erstellen. Aber wie ich fand, ist es mit der starken Schreibarchitektur von Swift nicht möglich." Sie meinen, Sie haben eine Instanz, und Sie wollen sie klonen? Swifts Typsystem hat eine Anzahl der Möglichkeiten, dies zu tun .. –

+0

Ich möchte eine Standard-Factory mit einer API erreichen, die als Parameter Typ akzeptiert und das Objekt zurückgibt.Das Problem liegt bei der Definition solcher Methode, der Eingabeparameter muss generischer Typ sein.Ich habe versucht, Generika zu verwenden, mit Typ-Constraint: 'create (Typ: T)', aber es beschwert sich, dass die statischen Methoden nicht sichtbar ist. –

3

.Type Verwendung ist der Schlüssel:

var f : Creatable.Type = Foo.self 

Und das nicht mehr gibt, die "nicht implementiert" Fehler. Kompletten Code unten:

protocol Creatable: class { 
    static func create() -> AnyObject 
} 

class Foo : Creatable { 
    static func create() -> AnyObject { 
     return Foo() as AnyObject 
    } 
} 

var f : Creatable.Type = Foo.self 
f.create() 
Verwandte Themen