TheSmartMonkey
TheSmartMonkey

Reputation: 1052

How to use list with for loops in go

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

Answers (1)

icza
icza

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

Related Questions