Как создать точную копию массива?

Я начинаю на языке Swift.

Как сделать точный дубликат массива?

Мне сложно найти информацию о дублировании массива в Swift.

Я попытался использовать .copy()

var originalArray = [1, 2, 3, 4]
var duplicateArray = originalArray.copy()

Ответ 1

Массивы имеют полную семантику значений в Swift, поэтому нет необходимости в каких-либо фантазии.

var duplicateArray = originalArray - это все, что вам нужно.


Если содержимое вашего массива является ссылочным типом, тогда да, это приведет только к копированию указателей на ваши объекты. Чтобы выполнить глубокую копию содержимого, вместо этого вы должны использовать map и выполнить копию каждого экземпляра. Для классов Foundation, которые соответствуют протоколу NSCopying, вы можете использовать метод copy():

let x = [NSMutableArray(), NSMutableArray(), NSMutableArray()]
let y = x
let z = x.map { $0.copy() }

x[0] === y[0]   // true
x[0] === z[0]   // false

Обратите внимание, что здесь есть подводные камни, в которых семантика значения Swift работает для защиты вас, например, поскольку NSArray представляет неизменяемый массив, его метод copy просто возвращает ссылку на себя, поэтому вышеприведенный тест даст неожиданные результаты.

Ответ 2

Нейт верен. Если вы работаете с примитивными массивами, все, что вам нужно сделать, это назначить duplicateArray для исходного массива.

Для полноты, если вы работаете с объектом NSArray, вы должны сделать следующее, чтобы сделать полную копию NSArray:

var originalArray = [1, 2, 3, 4] as NSArray

var duplicateArray = NSArray(array:originalArray, copyItems: true)

Ответ 3

Для обычных объектов, что можно сделать, это реализовать протокол, поддерживающий копирование, и сделать класс объекта реализующим этот протокол следующим образом:

protocol Copying {
    init(original: Self)
}

extension Copying {
    func copy() -> Self {
        return Self.init(original: self)
    }
}

И затем расширение Array для клонирования:

extension Array where Element: Copying {
    func clone() -> Array {
        var copiedArray = Array<Element>()
        for element in self {
            copiedArray.append(element.copy())
        }
        return copiedArray
    }
}

и это в значительной степени это, чтобы просмотреть код и образец, проверьте это gist

Ответ 4

Существует третий вариант ответа Nate:

let z = x.map { $0 }  // different array with same objects

* EDITED * начинается редактирование

Выше по существу то же самое, что и ниже, и фактически использование оператора равенства ниже будет работать лучше, поскольку массив не будет скопирован, если он не будет изменен (это по дизайну).

let z = x

Подробнее здесь: https://developer.apple.com/swift/blog/?id=10

* EDITED * редактируется здесь

Добавление или удаление этого массива не повлияет на исходный массив. Тем не менее, изменение любого из свойств объекта, которое имеет массив, будет видно в исходном массиве. Поскольку объекты в массиве не являются копиями (предполагается, что объекты массива хранятся, а не примитивные числа).