Как много информации разделяют переменные массива?
Сколько информации копируется / совместно используется, когда я назначаю одну переменную массива другой переменной массива?
int[] a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
int[] b = a;
a[0] = 42;
writefln("%s %s", a[0], b[0]); // 42 42
По-видимому, a
и b
имеют одинаковую полезную нагрузку, потому что 42 печатается дважды.
a ~= 10;
writefln("%s %s", a.length, b.length); // 11 10
Добавление к a
не изменяет b
, поэтому длина не кажется частью полезной нагрузки?
b = a;
a ~= 11;
b ~= 42;
writefln("%s %s", a[11], b[11]); // 11 42
Может ли соответствующая реализация D также печатать 42 42
? Может ли b ~= 42
перезаписать 11 внутри a
?
Когда точно разделены a
и b
друг от друга? Может быть, Ди исполняет какую-то корову на заднем плане?
2 ответа:
"массивы" в D на самом деле не существуют.
Срезы-это просто указатель и длина. Поэтому, когда вы назначаете их друг другу, указатель и длина копируются. Если вы измените целевые данные, то они будут видны во всех экземплярах срезов - но если вы увеличите один срез, другой будет по-прежнему использовать свою старую длину.
Обычно вы не можете "сжать" фактическую длину массива в памяти (хотя, конечно, вы можете уменьшить размер среза). длина, поэтому он "видит" меньше данных), так что это не вызывает проблем.
Надеюсь, это объясняет, что происходит.
Переменные массива В D эквивалентны
struct array!T{ size_t length; T* ptr; }
(плюс реализации для индексирования и нарезки)
Добавление является особенным в том, что оно может сохранить исходный срез и добавить к концу. Это происходит только тогда, когда либо емкость массива достаточно велика, либо перераспределение может расширяться в месте
Эти последние вещи сохраняются в GC