Быстрый поиск с присвоением внутри блока

#swift #struct #foreach #copy-on-write

#быстрый #структура #предначертание #копирование при записи

Вопрос:

Допустим, у меня есть это

 var array = [1,2,3]

array.forEach {
    array.append(17)
    print($0)
}
 

Он не будет зацикливаться вечно, вместо этого он будет печатать 1, 2 и 3, а затем массив будет содержать 6 элементов: [1,2,3,17,17,17]

Как это можно понять?

массив внутри блока является копией массива в тот момент, когда я звоню .append(17) , верно? А затем после цикла он присваивается массиву var? Или копия сделана заранее?

что на самом деле происходит?

Это:

 var array = [1,2,3]
var arrayCopy: [Int]

array.forEach {
    arrayCopy.append(17)
    print($0)
}

array = arrayCopy
 

или это:

 var array = [1,2,3]
var arrayCopy = array

arrayCopy.forEach {
    array.append(17)
    print($0)
}
 

Или что-то еще?

Комментарии:

1. «Это не будет зацикливаться вечно» — это очень хорошо.

Ответ №1:

Первый из них точен и работает нормально, но вы должны инициализировать arrayCopy его как пустой массив, как показано ниже:

 var array = [1,2,3]
var arrayCopy: [Int] = []

array.forEach {
    arrayCopy.append(17)
    print($0)
}

array = arrayCopy
 

Который даст вам тот же результат, что и вы, который вы уже добавили в свой массив, но это действительно, только если вы хотите сделать копию и поместить ее в свой исходный массив.

Комментарии:

1. Нет, извините, я не хочу это писать, я имел в виду, что хочу понять, что происходит под капотом.

Ответ №2:

Интересное наблюдение. Второй ответ выглядит более точным, когда вы создаете forEach, создается копия текущего массива и выполняется цикл по его элементам.

 var array = [1,2,3]
var arrayCopy = array

arrayCopy.forEach {
    array.append(17)
    print($0)
}
 

Если вы запустите следующий код в playground, вы получите вывод, показывающий элемент, добавленный в основной массив для каждого цикла цикла

 var array = [1,2,3]

array.forEach {_ in
    array.append(17)
    print(array)
}


//You will get following output 
//[1, 2, 3, 17]
//[1, 2, 3, 17, 17]
//[1, 2, 3, 17, 17, 17]