Avoiding const?
Timon Gehr
timon.gehr at gmx.ch
Wed Feb 22 04:57:02 PST 2012
On 02/22/2012 02:13 AM, ixid wrote:
> I apologize for what I'm sure is a very basic question. How should I do
> this elegantly?
>
> bool set[char[]];
Use bool set[string]. You cannot index an AA with a mutable array. The
declaration you give will be rejected by the compiler soon.
> //Stuff
> char[][] words = set.keys;
>
> It gives the error:
> Error: cannot implicitly convert expression (set.keys()) of type
> const(char)[][] to char[][]
> and I'm not sure why I can't copy const data to normal data.
Assuming you change the declaration to bool set[string], your error will
look like:
Error: cannot implicitly convert expression (set.keys()) of type
string[] to char[][].
(string is the same as immutable(char)[])
The reason for the immutable key requirement is that associative arrays
are impossible to be implemented efficiently if their keys can be
changed randomly from outside the data structure.
Here is why the assignment would make this possible:
Dynamic arrays are reference types. This means that they don't contain
the data. They just point to it. This means that multiple dynamic array
variables can point to the same data. This is called aliasing:
import std.stdio;
void main() {
int[] x = [1,2,3]; // a [...] literal creates a new array
writeln(x); // "[1,2,3]"
int[] y = x; // y now refers to ('aliases') the same array
y[0] = 2; // this therefore changes the data x refers to
writeln(x); // "[2,2,3]"
}
Now assume assigning immutable data to a mutable reference would succeed:
import std.stdio;
void main() {
immutable int[] x = [1,2,3]; // creates a new immutable array
int[] y = x; // creates mutable-immutable aliasing (compile error)
y[0] = 2; // this would then change x, which is illegal because
it is immutable
}
import std.stdio;
void main() {
immutable int[] x = [1,2,3]; // create a new array
int[] y = x.dup;// make a mutable copy of it; this actually copies
the data
y[0]=2;
writeln(x); // "[1,2,3]" (x is unchanged, good)
}
The general issue is still there if immutable is burried two references
deep.
import std.stdio;
void main(){
immutable(int)[][] x = [[1],[2],[3]];
int[][] y = x; // error
y[0][0] = 2;
}
However, there is no built-in functionality to copy all the immutable
data that is reachable from the top.
import std.stdio;
void main(){
immutable(int)[][] x = [[1],[2],[3]];
auto y = new int[][](x.length); // create an array of the
appropriate length
foreach(i,e; x){
y[i] = e.dup; // e is of type immutable(int)[]
}
}
More information about the Digitalmars-d-learn
mailing list