- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
// Playground - noun: a place where people can play
import Cocoa
// Изначальный массив и ссылка на него
var originalArray: Int[] = [1, 2, 3]; // [1, 2, 3]
var extraArray = originalArray // [1, 2, 3]
// Поменяем во втором массиве элемент
extraArray[0] = 666
// Оппа изменился и в первом
extraArray // [666, 2, 3]
originalArray // [666, 2, 3] O_o
// Не делись!
extraArray.unshare()
// Теперь они живут своей жизнью
extraArray[0] = 333
extraArray // [333, 2, 3] okay
originalArray // [666, 2, 3]
// А вот тут будет наоборот
var anotherArray = originalArray // [666, 2, 3]
// auto unshare
anotherArray.append(-1)
anotherArray.removeLast()
anotherArray[0] = 777
anotherArray // [777, 2, 3]
originalArray // [666, 2, 3]
// Словари вообще не так себя ведут, всегда копирование
var originalDictionary = [ 1: "hello", 2: "world"]
var extraDictionary = originalDictionary
extraDictionary[1] = "no way"
originalDictionary // [ 1: "hello", 2: "world"]
extraDictionary // [ 1: "no way", 2: "world"]
Я восхвалял Свифт, а же его и обосру.
В Свифте есть массивы и словари. Так вот словари при присваивании или передаче как аргумента копируются. Окей. Теперь массивы. Они, оказывается, не копируются, а разделяют значения между собой! Т. е. передал массив в ф-цию, она там что-то испортила, массив испортился везде, где засветился.
Чтобы эту фигню остановить, нужно вызывать спец. функцию unshare
Но это еще не все. При некоторых операциях с массивами (потенциально меняющих их длину) unshare делается автоматически!
Предвижу классическую ошибку свифтокодеров: ожидал, что массив поменяется, а он не поменялся снаружи; или передал массив, поюзал, а он снаружи неожиданно испортился. Плюс путаница, что базовые типы ведут себя по-разному.
Оправдание Apple: мы хотели перформанс С-массивов в Свифте, поэтому сделали эту хрень.