I have some confusion regarding passign slices to function. Here is what I have readed:
Here are what I have understood: slice is a structure with a pointer to real data; when we are passing a slice to a function, we just copy a pointer, but the function is working with the same data as original function.
Here is my code:
type Example struct {
A int
B string
}
func foo(d []Example) {
for _, e := range d {
e.B = "bye"
}
}
func main() {
a := Example{}
a.A = 10
a.B = "hello"
b := Example{}
b.A = 10
b.B = "hello"
var c []Example
c = append(c, a)
c = append(c, b)
foo(c)
for _, e := range c {
fmt.Println(e.B)
}
}
I have passed slice of structs to a function and have changed the struct in the function. Why I have old values in the main function ?
Because it's a slice of structs, not a slice of pointers to structs. When you execute:
for _, e := range d
Inside the loop, e
is a copy of the element from the slice; modifying it does not modify what's in the slice. If d
were a []*Example
, it would work as you expected: https://play.golang.org/p/4ZgLETpq6d0
Note in particular that this has nothing at all to do with slices. If it were:
func foo(d Example) {
d.B = "bye"
}
You would run into the same problem: the function is modifying a copy of the struct, so the caller's copy is unaffected by what happens inside the function.
Another potential solution without using pointers would be to modify the values inside the slice, rather than in a copy of the element:
func foo(d []Example) {
for i := range d {
d[i].B = "bye"
}
}
Working example of this style: https://play.golang.org/p/_UJGU0XqaUO