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