2014-07-08 18 views
5

Come funziona std.conv.to!string(enum.member)? Com'è possibile che una funzione acquisisca un membro enum e restituisca il suo nome? Usa un'estensione per compilatore o qualcosa di simile? È un po 'normale per me da quando sono venuto dal mondo C/C++.Come funziona! Stringa (enum.member) funziona?

risposta

8

Quello che fa è utilizzare la riflessione del tempo di compilazione sul tipo enum per ottenere un elenco di membri (i nomi come stringhe) e i loro valori. Costruisce un'istruzione switch su queste informazioni per una rapida ricerca per ottenere il nome da un valore. to!SomeEnum("a_string") utilizza lo stesso principio, solo nella direzione opposta.

Le informazioni sulla riflessione del tempo di compilazione sono accessibili con __traits(allMembers, TheEnumType), che restituisce un elenco di stringhe che possono essere ricollegate per creare l'istruzione switch. Quindi lo __traits(getMember, TheEnumType, memberName) viene utilizzato per recuperare il corpo.

Tratti possono essere visti più qui: http://dlang.org/traits.html#allMembers

Tale allMembers si lavora su molti tipi, non solo classi come visto nell'esempio, ma anche struct, enums e più, anche moduli.

Il codice Phobos fonte ha alcuni esempi come EnumMembers in std.traits: https://github.com/D-Programming-Language/phobos/blob/master/std/traits.d#L3360

se la sorgente Phobos è un pò difficile da leggere, ma in linea di 3399, in fondo a quella funzione, si può vedere usando __traits(allMembers) come la sua fonte di dati. std.conv.to è implementato in termini di molte funzioni std.traits.

È possibile anche controllare la scheda capitolo di esempio per ottenere il capitolo di riflessione fuori dal mio libro di cucina D che discute questa roba troppo:

http://www.packtpub.com/discover-advantages-of-programming-in-d-cookbook/book

L'ultimo esempio in quel capitolo mostra come utilizzare molte delle le capacità di riflessione per costruire un piccolo dispatcher di funzioni basato su stringhe. Il capitolo seguente (non disponibile gratuitamente) mostra come creare un passaggio da esso per una migliore efficienza. In realtà è piuttosto semplice: basta inserire le istruzioni case all'interno di un foreach sui dati della compilazione e il compilatore D si srotolerà, quindi ottimizzerà la tabella di ricerca per te!