Массивы

Массивы

Объявления типов для массивов и ассоциативных массивов, особенно для многомерных массивов удобно читать справа налево. Примеры будут ниже с комментариями.

Статический массив

У него размер известен на этапе компиляции, (содержимое может меняться, если явно не запрещено):

// RU: "a1 - массив с тремя элементами типа int"
int[3] a1;

Динамический массив

У него и длина и содержимое меняется во время выполнения программы

// RU (справа-налево): "a2 - массив интов"
int[] a2;

Многомерные массивы

При одинаковом (по сути) синтаксисе, динамические многомерные массивы реализованы, как массивы указателей не массивы, а статические как "плоские прямоугольные матрицы" по соображениям более высокой производительности:

// RU: b1 - матрица: массив с тремя элементами-массивами по четыре элемента типа int в каждом
int[4][3] b1;

int[][] b2; // динамический массив массивов

Указатели

Указатели являются небезопасным средством языка.

int* p; // указатель p
p = a2.ptr; // теперь p указывает на первый элемент a2
int*[] p1; // p1 - динамический массив указателей

Слайсы (срезы)

Операция среза создает ссылку на непрерывный диапазон ячеек исходного массива

int[] a1 = [3,4,5,6,7];
auto a2 = a1[1..3]; // [4,5,6]
auto a3 = a1[]; // ссылка на все содержимое a1

$

В операциях доступа к элементам a[$] - это синоним a[a.length]

Поэлементные операции

a1[] *=2; // каждый элемент a1 увеличивается в два раза на месте
a1[1..3] +=1; // элементы с индексами 1 и 2 (3 - не входит) увеличиваются на единицу

Изменение длины массива

Динамические массивы позволяют менять их длину путем установки нового значения length:

int[] a1 = [3,4,5];
a1.length = 5;
a1[3]=6;
a1[4]=7;

Копирование элементов в другой массив

Для копирования элементов нужно в левой части присваивания использовать оператор среза []:

int[] a1 = [3,4,5];
int[] b1;
b1.length = a1.length;

b1[] = a1; // Копирование. 
// b1 = a1 // ! если сделать так, то b1 будет ссылкой на a1 

b1[0] = 10; // не затронет a1, если b1 - копия
writefln("%s %s", a1,b1); // [3, 4, 5] [10, 4, 5]

Копия через конкатенацию

Оператор ~ создает новый массив как объединение копий исходных

auto a1 = [3,4,5];
auto b1 = [6,7,8];
auto c1 = a1 ~ b1;
c1[0]=10;
writefln("%s %s %s", a1, b1, c1); // [3, 4, 5] [6, 7, 8] [10, 4, 5, 6, 7, 8]

Конкатенация на месте (добавление)

a ~= b; // массив a стал объединением a и b

Поэлементные операции в целевой массив

auto a1 = [3,4,5];
int[] b1;
b1.length = a1.length; // целевой массив той же длины
b1[] = a1[]+1;
writefln("%s %s", a1, b1); // [3, 4, 5] [4, 5, 6]

Свойства массивов

.init // для статического массива: инициализирует все элементы дефолтным значением
.length // количество элементов
.sizeof // длина в байтах
.ptr // указатель на первый элемент
.dup // изменяемая копия
.idup // неизменяемая копия
.sort, .reverse // сортировка, обратный порядок на месте
.reserve(N); // резервирование памяти как минимум для N элементов
.capacity // сколько может вместить массив без реаллокации (дорогостоящая операция)
myarray.foo(3); // вызов функции, идентично: foo(myarray, 3);

Строки

Строки - это неизменяемые массивы типа char:

string s1 = "abx";
immutable (char)[] s2 = "abx";
assert( s1==s2);
writefln("%s %s", s1, s2); // abx abx

results for ""

    No results matching ""