Reputation: 4540
I believe I was able to do this in an earlier version of the language, and indeed, code I wrote several months ago, which compiled fine then, does not compile now. Example:
immutable(X)[int] myhash;
myhash[5] = some_immutable_X; //previously fine.
myhash[5] = some_other_immutable_X; //previously fine also.
Now however, dmd complains with
Error: cannot modify immutable expression myhash[5]
I've experimented with some other possible syntax without success (e.g. (immutable X)[int]). It seems there is no longer a way to declare that the hash itself is mutable, but the contents are not? This seems like a fairly common use case: a data structure for storing references to things that ought not to be altered. Anyone have some insight into this?
Upvotes: 5
Views: 128
Reputation: 507
The simplest way I found to do it was to cast both the associative array and the element to mutable during insertion, like so:
cast()myhash[5] = cast()some_immutable_X;
I do something like this in my applications where I initialize immutable definitions loaded from external sources at runtime and then reference them in mutable entities, so I put a small generic example here: http://dpaste.dzfl.pl/3a4233e5ec82
Upvotes: 0
Reputation: 38287
If it ever worked, it was a bug (probably due to the use of void*
and incorrect casting somewhere in the AA implementation, since it hasn't been properly switched to templates yet AFAIK). You cannot mutate immutable
values, and when you do
myHash[5] = value;
and the elements in myHash
are immutable
, then you are attempting to mutate an immutable
value, even if it's the init
value for that type (since an AA element gets initialized with the init
value before it's assigned to, and the type system has no way of knowing whether the element was previously in the AA, so it can't treat the first assignment via []
as initialization and the others as assignment). If you want to have an AA of immutable
elements, then you're going to need another level of indirection so that the elements themselves are not immutable
but rather refer to something which is immutable
- e.g by using a mutable pointer to an immutable
type, or if you're dealing with classes, then use std.typecons.Rebindable
(since you can't have mutable class references to const
or immutable
objects).
Upvotes: 3
Reputation: 2413
This behaviour did not work before 2.061, it has been work from 2.061 to 2.066.1. And it is "fix" in 2.067.
More info: github pull and bug issue
Upvotes: 2