oinume journal

Scratchpad of what I learned

Go Tip: Don't take the address of loop variable

stackoverflow.com

If you take the address of loop variable, it may cause a bug which all values are same. You might expect following program prints 5 10 15 but it prints 15 15 15. That’s because loop variable v is initialized just once.

package main

import "fmt"

func main() {
    coll := []int{5, 10, 15}
    for _, v := range toPointers(coll) {
        fmt.Printf("%v ", *v)
    }
}

func toPointers(ints []int) []*int {
    pointers := make([]*int, len(ints))
    for i, v := range ints {
        pointers[i] = &v // XXX: mistake
    }
    return pointers
}

You can get expected result if you write like this:

package main

import "fmt"

func main() {
    coll := []int{5, 10, 15}
    for _, v := range toPointers(coll) {
        fmt.Printf("%v ", *v)
    }
}

func toPointers(ints []int) []*int {
    pointers := make([]*int, len(ints))
    for i, _ := range ints {
        pointers[i] = &ints[i]
    }
    return pointers
}