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