In the Swift Language Reference, under String Mutability它说:
您可以通过将特定字符串分配给变量(在这种情况下可以修改)来指示是否可以修改(或变异),或者指定常量(在这种情况下不能修改)
我不清楚可变的“它”是变量还是值。
例如,如果我写:
var s = ""
for i in 0...100 {
s += "a"
}
是否类似于创建NSMutableString
并调用appendString
100次(即线性费用)?
或者它类似于创建一系列更大的NSString
个实例并将它们与stringByAppendingString
组合(即二次成本)?
或许它会在幕后创建某种绳索结构,所以它是不可变的和线性的聚合?
答案 0 :(得分:2)
追加到这样的集合(虽然String
本身不是一个集合,但实际上你的characters
视图附加了该代码)是线性的,而不是二次的。 Swift中的一个字符串有一个内部缓冲区,当它填满时它的大小加倍,这意味着当你重复追加时,你会看到越来越少的重新分配。该文档描述了以这种方式附加为“摊销”的O(1)操作:大多数时候附加的是O(1),但有时它需要重新分配字符串的存储。
数组,集和词典具有相同的行为,但如果您知道要多次追加,也可以为数组保留特定容量(使用reserveCapacity(_:)
)。
所有这些集合都使用“copy-on-write”来保证值语义。在这里,x
和y
共享一个缓冲区:
let x = "a"
let y = x
如果你改变x
,它会获得一个新的,唯一的缓冲区副本:
x += "b"
// x == "ab"
// y == "a"
之后,x
有自己的缓冲区,因此后续的突变不需要复制。
x += "c" // no copy unless buffer is full