2011-12-24 5 views
22

Sto imparando D e ho visto un sacco di codice come questo:Operatore di esclamazione?

ushort x = to!ushort(args[1]); 

Presumo che ciò getta args[1] a ushort, ma qual è la differenza tra questo e cast(ushort)?

EDIT: E quali altri usi ha l'operatore punto esclamativo?

risposta

31

In D,

to!ushort(args[1]) 

è una scorciatoia per la modello di istanza

to!(ushort)(args[1]) 

ed è simile a

to<ushort>(args[1]) 

in linguaggi come C++/Java/C#.

Il punto esclamativo è notare il fatto che non si tratta di un argomento normale, ma di un argomento modello.

La notazione fa non parentesi angolari uso perché quelli sono ridicolmente difficile analizzare correttamente per un compilatore (che fanno la grammatica molto sensibile al contesto), il che rende ancora più difficile l'attuazione di una corretta compilazione. Vedi here per maggiori informazioni.

L'unico altro uso che conosco è solo l'operazione "non" unaria (ad esempio false == !true) ... Non riesco a pensare ad altri usi al momento.


Per quanto riguarda il cast:

cast(ushort) è un incontrollato cast, in modo da non un'eccezione se il valore è fuori portata.

to!ushort() è un contrassegnato con cast, quindi genera un'eccezione se il valore è fuori intervallo.

+0

grazie mille =] ottima risposta! – thwd

+3

Sembra anche che! è più un cast lessicale, per esempio per! string (f) è valido per floating point f e cast (string) f - not. –

+5

Vorrei sottolineare che tecnicamente parlando 'to! Ushort (val)' non è in realtà un cast. È una conversione che usa la funzione 'std.conv.to'. Viene controllato, ma se inizi a chiamarlo cast, rischi di creare confusione. La fusione viene eseguita solo con l'operatore del cast. –

3

Il punto esclamativo qui non è un operatore, è solo una parte del token della sintassi di istanziazione del modello esplicita (descritta in dettaglio here).

std.conv.to (docs) è un modello di funzione per la conversione tra tipi arbitrari. È implementato interamente nella libreria e non ha alcun supporto speciale nella lingua. Ha un ambito più ampio e diverso rispetto all'operatore di cast.

Il modello to accetta due tipi di parametri; un tipo "a" e un tipo "da", in questo ordine. Nell'esempio, il modello viene esplicitamente istanziato con il solo argomento tipo ushort per il parametro "a" e un secondo argomento tipo string (supponendo) dal primo parametro aviene automaticamente dedotto dall'argomento di funzione regolare passato al funzione (args[1]) come parametro "from".

La funzione risultante utilizza un parametro stringa e restituisce un ushort analizzato da tale stringa o genera un'eccezione se non è riuscita. L'operatore di cast non tenterà questo tipo di conversione di alto livello.

Nota che se c'è più di un parametro modello esplicito, o che il parametro ha più di un gettone in esso (ushort è un unico token parola chiave), è necessario avvolgere la lista dei parametri del modello tra parentesi:

ushort result; 
result = to!(typeof(result))(args[1]); 

In questo esempio, typeof, (, result e ) sono quattro token separati e pertanto sono necessarie le parentesi.

per rispondere alla tua ultima domanda, il token ! è utilizzato anche per l'unario operatore not, estraneo a istanze di modello:

bool yes = true; 
bool no = !yes; // 'no' is false 
2

È già ottenuto due risposte eccellenti da jA_cOp e Merhdad. Voglio solo rispondere direttamente alla domanda OP (qual è la differenza tra questo e cast (ushort)?) - La differenza è che cast(ushort)args[1] non funzionerà (non puoi trasmettere da una stringa a un uint proprio così), mentre il Il modello to!(type)(param) sa cosa fare con la stringa e come convertirlo nel tipo primitivo.

+0

grazie mille, questo ha senso. – thwd