2015-04-29 11 views
5

Credo di essere stato in grado di farlo in una versione precedente del linguaggio, e infatti, il codice che ho scritto diversi mesi fa, che compilato bene allora, non viene compilato ora. Esempio:In D, come posso dichiarare un hash di tipi immutabili che è esso stesso mutabile?

immutable(X)[int] myhash; 
myhash[5] = some_immutable_X; //previously fine. 
myhash[5] = some_other_immutable_X; //previously fine also. 

Ora però, DMD lamenta con

Error: cannot modify immutable expression myhash[5] 

Ho sperimentato con qualche altra possibile sintassi senza successo (per esempio (immutabile X) [int]). Sembra che non ci sia più un modo per dichiarare che l'hash stesso è mutevole, ma i contenuti non lo sono? Questo sembra un caso d'uso abbastanza comune: una struttura dati per memorizzare riferimenti a cose che non dovrebbero essere alterate. Qualcuno ha qualche idea in questo?

+0

È il valore X o un tipo di riferimento (cioè classe)? –

+0

Non funziona con nessuno dei due, ma funziona bene con 2.066.1 e prima di – Kozzi11

+0

X è una classe (cioè un riferimento). –

risposta

3

Se mai funzionato, è stato un bug (probabilmente a causa dell'uso di void* e la colata non corretta da qualche parte nella realizzazione AA, in quanto non è stato correttamente passato a modelli ancora AFAIK). Non si può mutare immutable valori, e quando lo fai

myHash[5] = value; 

e gli elementi in myHash sei immutable, allora si sta cercando di mutare un valore immutable, anche se è il valore init per quel tipo (dal momento che un elemento AA ottiene inizializzato con il valore init prima che sia assegnato a, e il sistema di tipi non ha modo di sapere se l'elemento era precedentemente nell'AA, quindi non può trattare il primo compito tramite l'[] come inizializzazione e gli altri come assegnazione). Se si desidera avere un AA degli elementi immutable, sarà necessario un altro livello di riferimento indiretto in modo che gli elementi stessi non siano immutable ma si riferiscano a qualcosa che è immutable - ad esempio utilizzando un puntatore mutabile a un tipo immutable, o se hai a che fare con le classi, usa std.typecons.Rebindable (dato che non puoi avere riferimenti di classe mutabili a oggetti const o immutable).

2

Questo comportamento non ha funzionato prima del 2.061, è stato utilizzato dalla 2.061 alla 2.066.1. Ed è "fix" in 2.067.

Maggiori informazioni: github pull e bug issue

0

Il modo più semplice che ho trovato per farlo è stato quello di lanciare sia l'array associativo e l'elemento di mutabile durante l'inserimento, in questo modo:

cast()myhash[5] = cast()some_immutable_X; 

faccio qualcosa come questa nel mio applicazioni in cui ho inizializzare definizioni immutabili caricati da fonti esterne in fase di runtime e quindi li faccio riferimento in entità mutabili, quindi metto qui un piccolo esempio generico: http://dpaste.dzfl.pl/3a4233e5ec82

Problemi correlati