Зрiзи

Зрiзи - це об'єкти типу T[] для будь-якого заданого типу Т. Зріз надає доступ до підмножини масиву значень Т, або просто вказує на весь масив. Зрiзи та динамічні масиви - це одне і те ж.

Зріз складається з двох елементів - вказівник на початковий елемент та довжину зрізу:

T* ptr;
// беззнакове 32-бiтне число на 32-бiтних платформах
// чи беззнакове 64-бiтне число на 64-бiтних платформах.
size_t length;

Отримання зрізу за допомогою виділення пам'яті

При створенні нового динамічного масиву, для зрiзу відразу видiляється частина пам'ятi:

auto arr = new int[5];
assert(arr.length == 5); // пам'ять, на яку посилається arr.ptr

Фактична виділена пам'ять у цьому випадку повністю керується збирачем сміття (GC або garbage collector). Повернутий зріз буде вказувати на існуючі елементи.

Отримання зрізу з існуючої пам'яті

За допомогою оператора зрізу можна також отримати зріз, який вказує на деякий вже існуючий блок пам'яті. Оператор зрізу може бути застосований до інших зрізів, статичних масивів, структур/класів, у яких було реалізовано метод opSlice і так далі.

У цьому виразі origin[початок .. кінець] оператор зрізу використовується для отримання зрізу всіх елементів origin від початок до елементу перед кінець:

auto newArr = arr[1 .. 4]; // iндекс 4 не врахований
assert(newArr.length == 3);
newArr[0] = 10; // змiнює newArr[0], який співпадає з arr[1]

Такі зрізи генерують новий доступ до існуючої пам'яті. Вони не створюють нову копію. Якщо жоден зрiз більше не містить посилання на пам'ять, або на її частину - вона буде очищена збирачем сміття.

Зрізи надають можливість писати дуже ефективний код. Наприклад, парсери зазвичай працюють з одним блоком пам'яті, просто посилаючись на неї за допомогою зрiзiв, без необхідності виділяти нових блоків пам'яті.

Як було зазначено у попередньому розділі, вираз [$] є скороченою формою для arr.length. Отже, arr[$] буде посилатись на елемент, який знаходиться за останнім елементом зрізу, таким чином буде згенеровано RangeError (якщо не була відключена перевiрка меж зрiзiв).

Додатково

rdmd playground.d