В целом, вы, кажется, понимаете вещи довольно хорошо, но вы, похоже, неправильно понимаете цель свойства ptr
. Он не указывает, ссылаются ли два массива на один и тот же экземпляр. Что он делает, так это дает вам указатель на то, что под ним находится массив C. Массив в D имеет свой length
как часть этого, так что это больше похоже на структуру с длиной и указателем на массив C, чем на массив C. ptr
позволяет получить массив C и передать его в код C или C ++. Вы, вероятно, не должны использовать его для чего-либо в чистом D-коде. Если вы хотите проверить, относятся ли две переменные массива к одному и тому же экземпляру, используйте оператор is
(или !is
, чтобы проверить, что это разные экземпляры):
assert(a is b); //checks that they're the same instance
assert(a !is b); //checks that they're *not* the same instance
Все, что ptr
будет равным для двух массивов, указывает на то, что их первый элемент находится в том же месте в памяти. В частности, их length
могут отличаться. Однако это означает, что любые перекрывающиеся элементы будут изменены в обоих массивах, если вы измените их в одном из них.
При изменении length
массива D пытается избежать перераспределения, но может принять решение о перераспределении, поэтому вы не можете полностью полагаться на то, будет ли он перераспределяться или нет. Например, он будет перераспределен, если не сделает этого, будет топать память другого массива (включая те, которые имеют то же значение для ptr
). Он также может перераспределить, если недостаточно памяти для изменения размера на месте. По сути, он будет перераспределен, если не сделает этого, помешает памяти другого массива, и может перераспределить или не перераспределить иначе. Так что, как правило, не стоит полагаться на то, будет ли массив перераспределяться или нет, когда вы устанавливаете его length
.
Я бы ожидал, что добавление всегда будет копировать в соответствии с документами, но в соответствии с вашими тестами оно действует так же, как length
(я не знаю, означает ли это, что документы должны быть обновлены или это ошибка - я думаю, что документы должны быть обновлены). В любом случае вы, безусловно, не можете полагаться на другие ссылки на этот массив, чтобы все еще ссылаться на тот же массив после добавления.
Что касается срезов, они работают так, как ожидалось, и широко используются в D, особенно в стандартной библиотеке Phobos. Срез - это диапазон для массива, а диапазоны - основная концепция Фобоса. Однако, как и многие другие диапазоны, изменение контейнера, для которого предназначен диапазон / срез, может сделать этот диапазон / срез недействительным. Вот почему, когда вы используете функции, которые могут изменять размеры контейнеров в Фобосе, вам нужно использовать функции с предваряющей стабильной (например, stableRemove()
или stableInsert()
), если вы не хотите рисковать аннулированием диапазонов, которые у вас есть к этому контейнер.
Кроме того, срез - это массив, аналогичный массиву, на который он указывает. Поэтому, естественно, изменение его length
или добавление к нему будет следовать всем тем же правилам, что и для изменения length
или добавлению к любому другому массиву, и поэтому он может быть перераспределен и больше не будет срезом в другой массив.
В значительной степени, вам просто нужно знать, что изменение length
массива любым способом может привести к перераспределению, поэтому вам следует избегать этого, если вы хотите, чтобы ссылки продолжали ссылаться на тот же экземпляр массива , И если вам абсолютно необходимо убедиться, что они не указывают на одну и ту же ссылку, то вам нужно использовать dup
, чтобы получить новую копию массива. Если вы вообще не связываетесь с length
массива, то ссылки на массивы (будь то срезы или ссылки на весь массив) будут продолжать счастливо ссылаться на тот же массив.
РЕДАКТИРОВАТЬ: Оказывается, документы должны быть обновлены.Все, что может изменить размер массива, попытается сделать это на месте, если оно может (так что он может не перераспределить), но будет перераспределять, если это необходимо, чтобы избежать растоптания в памяти другого массива или если у него недостаточно местаперераспределить на месте.Таким образом, не должно быть никакого различия между изменением размера массива путем установки его свойства length
и изменением его размера путем добавления к нему.
ADDENDUM: Любой, кто использует D, действительно должен прочитать эта статья о массивах и срезах.Это объясняет их довольно хорошо и должно дать вам гораздо лучшее представление о том, как работают массивы в D.