使用var时,Swift是否具有二次字符串连接?

时间:2016-10-04 20:02:25

标签: swift string mutability

In the Swift Language Reference, under String Mutability它说:

  

您可以通过将特定字符串分配给变量(在这种情况下可以修改)来指示是否可以修改(或变异),或者指定常量(在这种情况下不能修改)

我不清楚可变的“它”是变量还是

例如,如果我写:

var s = ""
for i in 0...100 {
  s += "a"
}

是否类似于创建NSMutableString并调用appendString 100次(即线性费用)?

或者它类似于创建一系列更大的NSString个实例并将它们与stringByAppendingString组合(即二次成本)?

或许它会在幕后创建某种绳索结构,所以它是不可变的线性的聚合?

1 个答案:

答案 0 :(得分:2)

追加到这样的集合(虽然String本身不是一个集合,但实际上你的characters视图附加了该代码)是线性的,而不是二次的。 Swift中的一个字符串有一个内部缓冲区,当它填满时它的大小加倍,这意味着当你重复追加时,你会看到越来越少的重新分配。该文档描述了以这种方式附加为“摊销”的O(1)操作:大多数时候附加的是O(1),但有时它需要重新分配字符串的存储。

数组,集和词典具有相同的行为,但如果您知道要多次追加,也可以为数组保留特定容量(使用reserveCapacity(_:))。

所有这些集合都使用“copy-on-write”来保证值语义。在这里,xy共享一个缓冲区:

let x = "a"
let y = x

如果你改变x,它会获得一个新的,唯一的缓冲区副本:

x += "b"
// x == "ab"
// y == "a"

之后,x有自己的缓冲区,因此后续的突变不需要复制。

x += "c"   // no copy unless buffer is full