AJR
AJR

Reputation: 1671

Changing array element has no effect

There is something wrong with the compiler or my understanding of Go. I have a weird bug and have whittled it down to a simple example. For some reason I can't change the array directly within a loop.

    var nums [2]int
    for i, v := range nums {
        if i == 0 {
            nums[i+1]++
        } else {
            fmt.Print(v)
        }
    }

This increments nums[1] then prints it. So it should print 1 but it prints 0.

Upvotes: 0

Views: 79

Answers (2)

Andrew W. Phillips
Andrew W. Phillips

Reputation: 3601

When you use an array in an expression you get its "value" (ie, a complete new copy of the array). This includes using an array in the range expression of a loop. So when you print v you are printing the copy, but the actual nums array has been changed.

Looping on a slice instead of the array gives you what you expect:

    var nums [2]int
    for i, v := range nums[:] {
        if i == 0 {
            nums[i+1]++
        } else {
            fmt.Print(v)
        }
    }

Upvotes: 4

colm.anseo
colm.anseo

Reputation: 22037

The range creates a copy of the array (and its values), so it can iterate over them.

If you plan on mutating an array (or a slice of that matter) during iteration, it's best to reference the array/slice directly - as the v value will be a copy and in your code an old copy of the array.

So try something like:

var nums [2]int
for i := range nums {
    if i == 0 {
        nums[i+1]++
    } else {
        fmt.Print(nums[i])
    }
}

Playground

Upvotes: 2

Related Questions