Сколько информации разделяют переменные массива? - PullRequest
5 голосов
/ 09 января 2012

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

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 отделены друг от друга?D выполняет некоторые COW в фоновом режиме?

Ответы [ 2 ]

7 голосов
/ 09 января 2012

«Массивов» в D на самом деле не существует.

Срезы делают.

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

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

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

3 голосов
/ 10 января 2012

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

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

}

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

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

, эти последние вещи поддерживаются в GC

...