write protection in for loop?

80 views Asked by At

One strange behaviour: I have several objects and arrays:

for image in images {
        for nextID in image.parts {
            if nextID.number != 0 {
                if let n = primaryLookUp[nextID.number] {
                    image.parts[0].newID = 0
                    nextID.newID =  0  // cannot assign!!!
                }
            }
        }

nextID is simply going through the array of .parts. Does ist become a "let" assignment so I couldn't change anything later on? The

image.parts[0].newID = 0

is valid!

1

There are 1 answers

2
vacawama On

I believe this is the explanation for what you are seeing:

The value of a loop variable is immutable, just as if it had been assigned with let.

In your first loop, images is an array of objects (defined by a class). Since a class object is a reference type, you can alter the fields of the object. Only the loop variable image in that case cannot be assigned.

In your second loop, image.parts is an array of structs. Since a struct is a value type, the entire nextID and its fields will be immutable within the loop.

If you add var to the second loop, you will be able to assign to nextID.newID:

for image in images {
    for var nextID in image.parts {
        if nextID.number != 0 {
            if let n = primaryLookUp[nextID.number] {
                image.parts[0].newID = 0
                nextID.newID =  0  //  this now works!!!
            }
        }
    }
}

but, you are changing a copy of the nextID (since structures copies are by value) and you are not changing the nextID contained in the original image object.