我正在阅读文档,并且不断对语言的一些设计决策摇头。但真正让我感到困惑的是数组是如何处理的。
我冲到操场上尝试了这些。你也可以试试。所以第一个例子:
var a = [1, 2, 3] var b = a a[1] = 42 a b
Here aand bare both [1, 42, 3],我可以接受。数组被引用 - 好的!
a
b
[1, 42, 3]
现在看这个例子:
var c = [1, 2, 3] var d = c c.append(42) c d
c是[1, 2, 3, 42]但是d是[1, 2, 3]。也就是说,d在上一个例子中看到了变化,但在这个例子中没有看到。文档说那是因为长度改变了。
c
[1, 2, 3, 42]
d
[1, 2, 3]
现在,这个怎么样:
var e = [1, 2, 3] var f = e e[0..2] = [4, 5] e f
e是[4, 5, 3],这很酷。有一个多索引替换很好,但f即使长度没有改变,仍然看不到变化。
e
[4, 5, 3]
f
总而言之,如果您更改 1 个元素,对数组的常见引用会看到更改,但如果您更改多个元素或附加项目,则会创建一个副本。
这对我来说似乎是一个非常糟糕的设计。我这样想对吗?有没有理由我不明白为什么数组应该这样?
编辑 :数组已更改,现在具有值语义。理智多了!
请注意, Xcode beta 3 版本(博客文章) 中更改了数组语义和语法 ,因此该问题不再适用。以下答案适用于 beta 2:
这是出于性能原因。基本上,他们尽量避免复制数组(并声称“类似 C 的性能”)。引用语言书:
对于数组,仅当您执行可能修改数组长度的操作时才会进行复制。这包括追加、插入或删除项目,或使用范围下标替换数组中的一系列项目。
我同意这有点令人困惑,但至少对它的工作原理有一个清晰而简单的描述。
该部分还包括有关如何确保唯一引用阵列、如何强制复制阵列以及如何检查两个阵列是否共享存储的信息。