如何在Swift中创建不可变数组?
对文档的肤浅阅读表明你可以做到
let myArray = [1,2,3]
但遗憾的是,这实际上产生了一个可变的,固定大小的数组。这种可变性创造了通常的谜题,其中出现了未预料到的别名和函数,这些谜题会改变它们的参数:
let outterArray = [myArray, myArray]
outterArray[0][0] = 2000
outterArray //=> [[2000,2,3],[2000,2,3]] surprise!
func notReallyPure(arr:Int[]) -> () { arr[0] = 3000 }
notReallyPure(myArray)
myArray // => [3000,2,3]
没有比C好多了。
如果我想要不变性,最好将它包装在NSArray
中,如此:
let immutableArray = NSArray(myArray: [1,2,3])
这看起来很疯狂。我在这里缺少什么?
更新时间(2015-07-26):
这个问题可以追溯到斯威夫特的早期阶段。从那时起,Swift已经更新,因此不可变数组实际上是不可变的,如下面的答案所示。
答案 0 :(得分:27)
这已经改变了Xcode 6 beta 3.虽然数组过去是半可变的,正如你所描述的那样,它们的元素可以更改但是它们的长度是固定的,现在不可变数组与字典共享相同的语义:
从Xcode 6 beta 3发行说明:
•Swift中的数组已经完全重新设计,具有像Swift一样的字典和字符串等完整值语义。这解决了各种可变性问题 - 现在是' let'数组是完全不可变的,而且是一个&var;数组是完全可变的 - 用Dictionary和String正确组合,并解决其他更深层次的问题。如果您习惯使用NSArray或C数组,则值语义可能会令人惊讶:数组的副本现在使用有效的延迟复制实现生成所有元素的完整且独立的副本。这是Array的一个重大变化,仍有一些性能问题需要解决。请 !有关更多信息,请参阅Swift编程语言。 (17192555)
Swift手册中有关阵列的原始信息已于2014年7月7日更新,以反映beta 3的变化。 (如果您在Mac上使用iBooks,就像我一样,您可能需要删除并重新下载它以获取7月7日的更新 - 我无法自动更新。)< / p>
答案 1 :(得分:8)
似乎是一个错误,很快就会修复。
问题:
与let for Array和Dictionary
不一致
最终答案:
这被认为是一个错误,而不是一个功能,并将被修复为 后来的Beta。
-Chris
答案 2 :(得分:1)
对此没有很好的答案,这很奇怪。
但是,您可以通过调用yourArray.unshare()
来防止数组在流经您的程序时意外突变。这会导致在将数组分配给新变量时复制该数组。
答案 3 :(得分:1)
现在可以。
如果将数组或字典分配给常量,则该数组或字典是不可变的,并且其大小和内容不能更改。
所以现在
let myArray = [1,2,3]
生成完全不可变的数组。耶!
答案 4 :(得分:0)
恕我直言,最简单的解决方法是将其包装在闭包中,如下所示:
let mutableElements = [0,1,2,3]
let reallyImmutable = {[0,1,2,3]}
println(mutableElements)
for i in 0..mutableElements.count { mutableElements[i] *= -1 }
println(mutableElements) // [0, -1, -2, -3]
println(reallyImmutable())
for i in 0..reallyImmutable().count { reallyImmutable()[i] *= -1 }
println(reallyImmutable()) // [0, 1, 2, 3]
println(reallyImmutable()[2]) // 2
let anotherImmutable = { reallyImmutable().map{ $0 * $0 } }
println(anotherImmutable()) // [0, 1, 4, 9]
您为声明和()为每次访问支付额外费用{},但这也使您的代码能说明一切。
Dan the Mutable Programmer
P.S。写了一个包装类ImmutableArray。