Как массив в быстром глубоком копировании сам при копировании или назначении - PullRequest
0 голосов
/ 25 февраля 2019

Мы все знаем, что массив в swift является типом значения, это означает, что после копирования или присвоения массива другому, изменение нового массива не повлияет на старый.Например:

var a = ["a", "b", "c", "d", "e"]
var b = a
b[0] = "1"
print(a[0]) // a
print(b[0]) // 1

Но мне интересно, как может работать массив.Длина для массива 'var' является динамической.Обычно мы должны выделить некоторую кучу памяти, чтобы содержать все значения.И я просматриваю некоторые исходные коды для struct Array, подчеркивающий буфер для массива реализован с использованием класса.Но при копировании структуры, которая содержит член указателя класса или памяти, класс и выделенная память не будут скопированы по умолчанию.

Так как же массив может скопировать свой буфер при копировании или назначении его другому?

1 Ответ

0 голосов
/ 25 февраля 2019

Назначение любого struct (например, Array) приводит к полному копированию содержимого структуры.Там нет особого поведения для Array.Буфер, в котором хранятся элементы Array, на самом деле не является частью структуры.Указатель на этот буфер, хранящийся в куче, является частью структуры Array, что означает, что при назначении указатель буфера копируется, но он все еще указывает на тот же буфер.

Все операции мутации в Array выполняют проверку, чтобы определить, есть ли в буфере уникальная ссылка.Если так, то алгоритм продолжается.В противном случае создается копия буфера, и указатель на новый буфер сохраняется в этом экземпляре Array, затем алгоритм продолжает работу, как и ранее.Это называется Копировать при записи (CoW).Обратите внимание, что это не автоматическая функция всех типов значений.Это просто реализованная вручную функция нескольких стандартных типов библиотек (например, Array, Set, Dictionary, String и другие).Вы могли бы даже реализовать это самостоятельно для своих собственных типов.

Когда происходит CoW, он не делает какое-либо глубокое копирование.Он будет копировать значения, что означает:

  • В случае типов значений (struct, enum, кортежи) значения являются самими кортежами struct / enum /.В этом случае глубокая и мелкая копии - это одно и то же.
  • В случае ссылочных типов (class) копируемое значение - ссылка .Ссылочный объект не копируется.Один и тот же объект указывается как старой, так и скопированной ссылкой.Таким образом, это мелкая копия.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...