我认为交换Swift数组的第0项和第1项是合法的,如下所示:
但我看到不一致的行为取决于我如何编码。
func test() {
class Test {
var array = ["foo", "bar"]
func swap1() { // PRODUCES STRANGE RESULT
array.insert(array.removeAtIndex(0), atIndex:1)
print("---swap1---", xs:array)
}
func swap2() { // PRODUCES EXPECTED RESULT
let item = array.removeAtIndex(0)
array.insert(item, atIndex:1)
print("---swap2---", xs:array)
}
func swap3() { // PRODUCES EXPECTED RESULT
var array = ["foo", "bar"]
array.insert(array.removeAtIndex(0), atIndex:1)
print("---swap3---", xs:array)
}
func print(fn: String, xs: [String]) {
println(fn)
for x in xs { println(x) }
}
}
Test().swap1()
Test().swap2()
Test().swap3()
}
---swap1---
foo
foo
bar
---swap2---
bar
foo
---swap3---
bar
foo
出乎意料地(对我来说),swap1()克隆第0个元素而不是删除它,从重复的" foo"在上面的swap1输出中。似乎产生这种行为的特征是
我的问题:为什么swap1()表现不同?
答案 0 :(得分:2)
在同一声明中有两个array
的变换器。这通常是一个坏主意,导致未定义的行为。这与你不想做的原因相同:
a = a++ + a++;
从人的角度来看,很明显您首先删除了一个项目,然后将其添加回已删除的数组中。
从编译器的角度来看,它必须做3件事来修改数组:1)读取原始数组的内容,2)修改内容,3)将它们写回。编译器必须在语句中执行两次:
array.insert(array.removeAtIndex(0), atIndex:1)
您希望编译器执行此操作:
1) temp1 = array
2) temp1.removeItem
3) array = temp1
4) temp2 = array
5) temp2.addItem
6) array = temp2
但确实如此:
1) temp1 = array
2) temp2 = array
3) temp2.removeItem
4) array = temp2
5) temp1.addItem
6) array = temp1
编译器的操作顺序是允许的,这就是为什么你不应该在同一个语句中放置两个mutator。
答案 1 :(得分:0)
这似乎是如何在Swift中处理数组的副作用。我相信Apple仍在试图找出在Swift中处理可变/不可变数组的最佳方法,而且这种行为很可能会改变(并且已经在beta版中发生了变化。
这是一篇很好的文章(或文章流,详细介绍了迄今为止的一些行为和变化):
http://blog.human-friendly.com/swift-arrays-the-bugs-the-bad-and-the-ugly-incomplete