Как много информации разделяют переменные массива?


Сколько информации копируется / совместно используется, когда я назначаю одну переменную массива другой переменной массива?

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 5

2 ответа:

"массивы" в D на самом деле не существуют.

Ломтики делают.

Срезы-это просто указатель и длина. Поэтому, когда вы назначаете их друг другу, указатель и длина копируются. Если вы измените целевые данные, то они будут видны во всех экземплярах срезов - но если вы увеличите один срез, другой будет по-прежнему использовать свою старую длину.

Обычно вы не можете "сжать" фактическую длину массива в памяти (хотя, конечно, вы можете уменьшить размер среза). длина, поэтому он "видит" меньше данных), так что это не вызывает проблем.

Надеюсь, это объясняет, что происходит.

Переменные массива В D эквивалентны

struct array!T{
    size_t length;
    T* ptr;

}

(плюс реализации для индексирования и нарезки)

Добавление является особенным в том, что оно может сохранить исходный срез и добавить к концу. Это происходит только тогда, когда либо емкость массива достаточно велика, либо перераспределение может расширяться в месте

Эти последние вещи сохраняются в GC