I'm a Python programmer enjoying Go. The thing that trips me up must often is the use of references; I have mastered it (mostly) but then on occasion something baffles me, such as this one.
I have a simple type ('Fixture'):
type Fixture struct {
Probabilities *[]float64
}
If I populate the Probabilities field for a single instance of this type, everything is fine:
c := appengine.NewContext(r)
f := Fixture{}
p := []float64{}
p = append(p, 0.5)
p = append(p, 0.2)
p = append(p, 0.3)
f.Probabilities = &p
c.Infof("%v", *f.Probabilities)
2013/03/19 07:37:36 INFO: [0.5 0.2 0.3]
However if I try and populate this field for an array of these types, the code compiles but the field value is always nil:
c := appengine.NewContext(r)
fixtures := []Fixture{}
f := Fixture{}
fixtures = append(fixtures, f)
for _, f := range fixtures {
p := []float64{}
p = append(p, 0.5)
p = append(p, 0.2)
p = append(p, 0.3)
f.Probabilities = &p
}
for _, f := range fixtures {
// c.Infof("%v", *f.Probabilities) // causes error
c.Infof("%v", f.Probabilities)
}
2013/03/19 07:37:41 INFO: <nil>
I guess I'm not understanding how arrays/slices work, particularly with respect to references. Can anyone point out where I'm going wrong ?
Thanks!
In the range statement
for _, f := range fixtures { ... }
f
is a newly declared local variable of type Fixture
. It's not a reference to anything. So after setting up its values, it has to be put into to the fixtures
slice.
package main
import "fmt"
type Fixture struct {
Probabilities *[]float64
}
func main() {
fixtures := []Fixture{}
f := Fixture{}
fixtures = append(fixtures, f)
for i, f := range fixtures {
p := []float64{}
p = append(p, 0.5)
p = append(p, 0.2)
p = append(p, 0.3)
f.Probabilities = &p
fixtures[i] = f
}
for _, f := range fixtures {
fmt.Printf("%v", f.Probabilities)
}
}
(Also here)
Output
&[0.5 0.2 0.3]
Store the element value in the slice. For example,
package main
import "fmt"
type Fixture struct {
Probabilities *[]float64
}
func main() {
fixtures := make([]Fixture, 1)
for i := range fixtures {
p := []float64{0.5, 0.2, 0.3}
fixtures[i] = Fixture{Probabilities: &p}
}
for _, f := range fixtures {
fmt.Println(*f.Probabilities)
}
}
Output:
[0.5 0.2 0.3]