2014-11-14 13 views
10

Kommend von C++, versuche ich einige Metaprogrammierung in Swift. Zum Beispiel möchte ich eine Metafunktion implementieren, die zwei Zahlen hinzufügt. Ich habe so etwas wie dies versucht:Metaprogrammierung in Swift

protocol IntWrapper { 
    class var value: Int { get } 
} 

struct A: IntWrapper { 
    static let value = 5 
} 

struct B: IntWrapper { 
    static let value = 7 
} 

struct Sum<T: IntWrapper, U: IntWrapper>: IntWrapper { 
    static let value = T.value + U.value 
} 

Das aber funktioniert nicht: (. Oder einfach nur abstürzt, manchmal) Xcode beklagt, dass T.Type hat kein Mitglied value

Wie implementieren solche Funktionalität?

+0

Hey Sir .... Fast ein Jahr später ... Haben wir Neuigkeiten über Swift und Metaprogrammierung? –

Antwort

8

static Gespeicherte Eigenschaften werden (derzeit) nicht für generische Objekte unterstützt. Wenn ich Ihren Code auf einem Spielplatz setzen, bekomme ich tatsächlich diesen Fehler:

Playground execution failed: <EXPR>:23:5: error: static variables not yet supported in generic types 
    static let value = T.value + U.value 
    ^~~~~~ 

Sie umgehen können, dass durch stattdessen eine berechnete Eigenschaft verwenden (was gewesen sein könnte, was Sie in erster Linie wollte sowieso):

struct Sum<T: IntWrapper, U: IntWrapper>: IntWrapper { 
    static var value: Int { 
     return T.value + U.value 
    } 
} 

Hinweis: Da es sich um eine berechnete Eigenschaft ist, müssen Sie value mit var und nicht let erklären.

Mit diesen Änderungen, println(Sum<A, B>.value) Drucke 12 wie Sie erwarten würden.

+0

Um ehrlich zu sein, bin ich mir nicht sicher, was ich wollte (im Sinne der Semantik der Sprache). Das endgültige Ziel ist, dass, sobald alle Optimierungen aktiviert sind, 'Sum .value' im resultierenden Binärcode auf eine Konstante reduziert wird. –

0

Es scheint mir, dass Sie Ihre Definitionen übereinstimmen müssen und das Protokoll anders implementieren müssen. (Ich bin kein geschickter Entwickler, aber ich habe das Lernen als ich die Leute auf Stackoverflow helfen.)

protocol IntWrapper { 
    static var value : Int { get } 
} 
struct A: IntWrapper { 
    static var value : Int { get { 5 } } 
} 

Sie wurden für einen class var Aufruf, aber dann definiert man einen static let. Subtile Differenz, aber ich denke, dass es hier zählt.

+0

Protokolle können keine statischen Eigenschaften haben, der Compiler gibt eine Fehlermeldung aus, wenn Sie es versuchen. –

Verwandte Themen