Slices sind Objekte des Types T[]
für einen beliebigen Typen T
.
Slices sind eine Untermenge (Sicht) oder die gesamte Menge
eines Arrays.
Dynamische Arrays sind Slices.
Ein Slice beinhaltet zwei Eigenschaften: (1) einen Zeiger auf das erste Element und (2) die Länge des Slices:
T* ptr;
size_t length;
size_t
entspricht dem Datentypen der maximalen Arraygröße der Zielplatform,
z.B. uint
auf 32-bit Architekturen und ulong
auf 64-bit Architekturen
(für detailliertere Informationen gehe zurück in das Datentypen-Kapitel).
new
Bei der Erstellung eines dynamischen Arrays wird ein Slice zum zugewiesenen Speicher zurückgegeben.
auto arr = new int[5];
assert(arr.length == 5); // Speicheraddresse in arr.ptr
Der eigentliche Speicher wird von der automatischen Speicherbereinigung (Garbage Collection) verwaltet. Ein Slice stellt nur die Menge an Elementen dar.
Der Slice-Operator kann auch benutzt werden, um auf bestehenden Speicher zu zeigen.
Der Slice-Operator kann auf einen anderen Slice, auf statische Arrays, auf
Strukturen und Klassen, welche opSlice
implementieren, und ein paar andere Objekte
angewendet werden.
Beim Ausdruck arr[Start .. Ende]
gibt der Slice-Operator eine Teilmenge
der Elemente von arr
anfangend bei Start
bis ausschließlich Ende
zurück.
auto newArr = arr[1 .. 4]; // Index 4 wird NICHT mit einbezogen
assert(newArr.length == 3);
newArr[0] = 10; // ändert newArr[0] und somit arr[1]
Solche Slices erstellen keine Kopie vom Speicher, sondern geben nur eine Untermenge (Sicht) des Arrays an. Wenn kein Slice mehr zum Speicher oder zu einer Untermenge zeigt, wird der Speicher bei der Garbage Collection gelöscht.
Mit Slices kann speichereffizienter Code geschrieben werden, welcher mit nur einem Block an Speicher arbeitet und Sichten auf Unterbereiche des Speicherblockes zur Vermeidung neuer Speicherallokationen benutzt.
Wie im vorherigen Kapitel gezeigt, ist arr[$]
eine Kurzform von
arr[arr.length]
. Es wird versucht auf das Element nach dem Ende des Slices
zuzugreifen, was eine RangeError
-Exception generiert, sofern die Compiler-Option
bounds-checking
nicht deaktiviert wurde.