arraysswiftloopsfor-in-loop

Does for ... in loop loop through a copy of a sequence?


I came across such statements as the following in Matt Neuburg's iOS 13 Programming Fundamentals with Swift:

When you cycle through a sequence with for...in, what you’re actually cycling through is a copy of the sequence. That means it’s safe to mutate the sequence while you’re cycling through it:

And the author supplied the following example for the above statements:

var s : Set = [1,2,3,4,5]
for i in s {
    if i.isMultiple(of:2) {
        s.remove(i)
    }
} // s is now [1,3,5]

In the example above, we can see that the original array was altered from [1,2,3,4,5,6] to [1,3,5]. That means the array itself was changed. So, the for in loop wasn't looping through a copy of the original array but the array itself. That seems to contradict the author's statements above.

So, I'm not sure whether the author's statements are true or not. Would anyone please clarify this matter? Thank you very much.


Solution

  • The wording might be a bit misleading at first sight, but the statement that for i in s loops through a copy of the original s is true. If it wasn't true, you'd get an out of bounds exception or an unexpected result (some elements of the collection being skipped), since you would be mutating a collection while you are iterating through it.

    When you create the loop with for i in s, a copy of s is created and the iteration happens through that copy. However, when you access s inside the body of the loop, you are accessing the original s and hence mutating that, not mutating the copy that the loop is iterating through.