12.6.5 Scalar Arrays and Associative Arrays

The D language supports scalar arrays, which correspond directly in concept and syntax with arrays in C. A scalar array is a fixed-length group of consecutive memory locations that each store a value of the same type. You access scalar arrays by referring to each location with an integer starting from zero. In D programs, you would usually use scalar arrays to access array data within the operating system.

For example, you would use the following statement to declare a scalar array sa of 5 integers:

int sa[5];

As in C, sa[0] refers to the first array element, sa[1] refers to the second, and so on up to sa[4] for the fifth element.

The D language also supports a special kind of variable called an associative array. An associative array is similar to a scalar array in that it associates a set of keys with a set of values, but in an associative array the keys are not limited to integers of a fixed range. In the D language, you can index associative arrays by a list of one or more values of any type. Together the individual key values form a tuple that you use to index into the array and access or modify the value that corresponds to that key. Each tuple key must be of the same length and must have the same key types in the same order. The value associated with each element of an associative array is also of a single fixed type for the entire array.

For example, the following statement defines a new associative array aa of value type int with the tuple signature string, int, and stores the integer value 828 in the array:

aa["foo", 271] = 828;

Once you have defined an array, you can access its elements in the same way as any other variable. For example, the following statement modifies the array element previously stored in a by incrementing the value from 828 to 829:

a["foo", 271]++;

You can define additional elements for the array by specifying a different tuple with the same tuple signature, as shown here:

aa["bar", 314] = 159;
aa["foo", 577] = 216;

The array elements aa["foo", 271] and aa["foo", 577] are distinct because the values of their tuples differ in the value of their second key.

Syntactically, scalar arrays and associative arrays are very similar. You can declare an associative array of integers referenced by an integer key as follows:

int ai[int];

You could reference an element of this array using the expression such as ai[0]. However, from a storage and implementation perspective, the two kinds of array are very different. The scalar array sa consists of five consecutive memory locations numbered from zero, and the index refers to an offset in the storage allocated for the array. An associative array such as ai has no predefined size and it does not store elements in consecutive memory locations. In addition, associative array keys have no relationship to the storage location of the corresponding value. If you access the associative array elements a[0] and a[-5], DTrace allocates only two words of storage, which are not necessarily consecutive in memory. The tuple keys that you use to index associative arrays are abstract names for the corresponding value, and they bear no relationship to the location of the value in memory.

If you create an array using an initial assignment and use a single integer expression as the array index, for example, a[0] = 2;, the D compiler always creates a new associative array, even though a could also be interpreted as an assignment to a scalar array. If you want to use a scalar array, you must explicitly declare its type and size.