2014-11-14 4 views
10

Provenendo da C++, sto provando a eseguire alcune metaprogrammazione in Swift. Ad esempio, vorrei implementare una metafunzione che aggiunge due numeri. Ho provato qualcosa di simile:Metaprogramming 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 
} 

Questo, tuttavia, non funziona: (. O semplicemente si blocca, a volte) Xcode si lamenta che T.Type non hai membro value

Come si può realizzare tale funzionalità?

+0

Hey sir's .... Quasi un anno dopo ... Abbiamo notizie su Swift e Metaprogramming? –

risposta

8

static le proprietà memorizzate non sono (attualmente) supportate su oggetti generici. Quando ho messo il codice in un parco giochi, in realtà ho ottengo questo errore:

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

È possibile aggirare questo utilizzando una proprietà calcolata, invece (che potrebbe essere stato quello che si voleva in primo luogo in ogni caso):

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

Nota: Poiché si tratta di una proprietà calcolata, è necessario dichiarare value con var e non let.

Con tali modifiche, println(Sum<A, B>.value) stampa come ci si aspetterebbe.

+0

Ad essere onesti, non sono proprio sicuro di cosa volessi (nel senso della semantica del linguaggio). L'obiettivo finale è che una volta abilitate tutte le ottimizzazioni, 'Sum .value' sarà ridotto a una costante nel codice binario risultante. –

0

Mi sembra necessario abbinare le definizioni e implementare il protocollo in modo diverso. (Io non sono uno sviluppatore veloce, ma ho imparato come aiuto la gente su StackOverflow.)

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

Stavi chiamando per un class var, ma poi è stato definito un static let. Differenza sottile, ma penso che importi qui.

+0

I protocolli non possono avere proprietà statiche, il compilatore genera un messaggio di errore se ci provi. –