Reputation: 1052
I want to append numbers to a list but my slice update the value only in the for loop.
How do I update it outside?
slice := []int{5,4,3,2,1}
for i := 0; i < len(slice); i++ {
slice := append(slice, i)
fmt.Println(slice)
}
fmt.Println(slice)
Actual result
[5 4 3 2 1 0]
[5 4 3 2 1 1]
[5 4 3 2 1 2]
[5 4 3 2 1 3]
[5 4 3 2 1 4]
[5 4 3 2 1]
Expected result
[5 4 3 2 1 0]
[5 4 3 2 1 1]
[5 4 3 2 1 2]
[5 4 3 2 1 3]
[5 4 3 2 1 4]
[5 4 3 2 1 0 1 2 3 4]
This code works in Python but in go there is something I don't catch
Upvotes: 1
Views: 646
Reputation: 418177
You don't store the result of append()
in your "original" slice
, because you use short variable declaration instead of assignment:
slice := append(slice, i)
The short variable declaration (since it's in a different block than the original slice
variable) creates a new variable (shadowing the outer slice
), and inside the loop you print this new variable. So the result of each append is only visible inside the loop body, and is lost when the iteration ends. Instead use assignment:
slice = append(slice, i)
However, when you do this, you'll get an infinite loop, because your loop condition is i < len(slice)
, and slice
grows in every iteration.
Instead you should do something like this (evaluate len(slice)
once and store it):
for i, length := 0, len(slice); i < length; i++ {
slice = append(slice, i)
fmt.Println(slice)
}
And output will be (try it on the Go Playground):
[5 4 3 2 1 0]
[5 4 3 2 1 0 1]
[5 4 3 2 1 0 1 2]
[5 4 3 2 1 0 1 2 3]
[5 4 3 2 1 0 1 2 3 4]
[5 4 3 2 1 0 1 2 3 4]
Note that you would get the same result if you'd use for range
, because that only evaluates the slice once:
for i := range slice {
slice = append(slice, i)
fmt.Println(slice)
}
Try this one on the Go Playground.
Upvotes: 1