I believe it is legal to swap the 0th and 1st item of a Swift array as follows:
But I am seeing inconsistent behaviour depending on how I code it.
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
Unexpectedly (to me), swap1() clones the 0th element rather than removes it, as can be seen from the repeated "foo" in the swap1 output above. The characteristics that seem to produce this behaviour are
My question: why does swap1() behave differently?
You have two mutators of array
in the same statement. This generally is a bad idea and results in undefined behavior. It's the same reason you don't want to do:
a = a++ + a++;
From the human point of view, it is clear that you are first removing an item, and then adding that back to the array it has been removed from.
From the compiler's point of view, it must do 3 things to modify the array: 1) read the contents of the original array, 2) modify the contents, and 3) write them back. The compiler has to do this twice in the statement:
array.insert(array.removeAtIndex(0), atIndex:1)
You expected the compiler to do this:
1) temp1 = array
2) temp1.removeItem
3) array = temp1
4) temp2 = array
5) temp2.addItem
6) array = temp2
but instead it did:
1) temp1 = array
2) temp2 = array
3) temp2.removeItem
4) array = temp2
5) temp1.addItem
6) array = temp1
The compiler's order of operations is allowable which is why you shouldn't put two mutators in the same statement.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With