I am not able to understand the behavior of this code block. What I am doing wrong and what should be the proper way to do this?
import (
"fmt"
"strconv"
)
type Record struct {
name *string
}
type person struct {
name string
}
func main() {
var Records []*Record
var persons []person
for i := 0; i < 10; i++ {
newValue := person{name: strconv.Itoa(i)}
persons = append(persons, newValue)
}
for _, personone := range persons {
newRecord := &Record{}
getName(newRecord, &personone)
Records = append(Records, newRecord)
}
for _, record := range Records {
fmt.Println(*record.name)
}
}
func getName(record *Record, value *person) {
record.name = &value.name
}
I am expecting this code to print 0 to 9, but it always prints 9, the last value.
for _, personone := range persons {
in this statement personone
is a variable that is declared once and is overwritten on every iteration.
Then you obtain its address in this statement getName(newRecord, &personone)
.
So you pass the same address every time, which is changed in every iteration.
So you end up having the same value, since you have assigned the same address.
How to fix: don't use pointers if you don't actually need them.
A super dirty hack would be to make a copy of the structure explicitly https://play.golang.org/p/Sp4xD88rfvE
for _, personone := range persons {
personone := personone // <-- see here
newRecord := &Record{}
getName(newRecord, &personone)
Records = append(Records, newRecord)
}
but I really would not recommend you doing that