I’m currently engaged in writing my second Go program - the first was a modified form of Hello World called Hello Pete - and I have encountered an aspect of slices which I am struggling to understand. I’m hoping that someone here will be kind enough to assist with an explanation.
I’m looking to read a csv file one record at a time, extract a subset of the fields and use them to populate a slice of string slices. My problem lies in the final part of the process.
I’ve tried to reproduce the behaviour I am seeing both here and in the playground.
package main
import (
"fmt"
)
func main() {
mySOS := make([][]string, 1)
fmt.Printf("mySliceOfSlices is of type %T and has value %v\n\n", mySOS, mySOS)
row0 := []string{"Twas", "brillig", "and", "the", "slithy", "toves"}
row1 := []string{"did", "gyre", "and", "gimble", "in", "the"}
row2 := []string{"wabe", "all", "mimsey", "were", "the", "borogoves"}
// row3 := []string{"and", "the", "mome", "raths", "outgrabe", "."}
s := make([]string, 3)
s[0] = row0[2]
s[1] = row0[3]
s[2] = row0[4]
fmt.Printf("s is of type %T and has value %v\n", s, s)
mySOS = append(mySOS, s)
fmt.Printf("mySliceOfSlices is of type %T and has value %v\n\n", mySOS, mySOS)
s[0] = row1[2]
s[1] = row1[3]
s[2] = row1[4]
fmt.Printf("s is of type %T and has value %v\n", s, s)
mySOS = append(mySOS, s)
fmt.Printf("mySliceOfSlices is of type %T and has value %v\n\n", mySOS, mySOS)
s[0] = row2[2]
s[1] = row2[3]
s[2] = row2[4]
fmt.Printf("s is of type %T and has value %v\n", s, s)
mySOS = append(mySOS, s)
fmt.Printf("mySliceOfSlices is of type %T and has value %v\n", mySOS, mySOS)
}
https://play.golang.org/p/o0ufVU3sBzR
My puzzlement is over the fact that mySOS always ends up being fully populated with the final slice from the test data. After spending a considerable amount of time staring at it I tried a slightly different approach which can be seen here.
package main
import (
"fmt"
)
func main() {
mySOS := make([][]string, 1)
fmt.Printf("mySliceOfSlices is of type %T and has value %v\n\n", mySOS, mySOS)
row0 := []string{"Twas", "brillig", "and", "the", "slithy", "toves"}
row1 := []string{"did", "gyre", "and", "gimble", "in", "the"}
row2 := []string{"wabe", "all", "mimsey", "were", "the", "borogoves"}
// row3 := []string{"and", "the", "mome", "raths", "outgrabe", "."}
/*
s := make([]string, 3)
s[0] = row0[2]
s[1] = row0[3]
s[2] = row0[4]
*/
// fmt.Printf("s is of type %T and has value %v\n", s, s)
mySOS = append(mySOS, row1[2:5])
fmt.Printf("mySliceOfSlices is of type %T and has value %v\n\n", mySOS, mySOS)
/*
s[0] = row1[2]
s[1] = row1[3]
s[2] = row1[4]
*/
// fmt.Printf("s is of type %T and has value %v\n", s, s)
mySOS = append(mySOS, row0[2:5])
fmt.Printf("mySliceOfSlices is of type %T and has value %v\n\n", mySOS, mySOS)
/*
s[0] = row2[2]
s[1] = row2[3]
s[2] = row2[4]
*/
// fmt.Printf("s is of type %T and has value %v\n", s, s)
mySOS = append(mySOS, row2[2:5])
fmt.Printf("mySliceOfSlices is of type %T and has value %v\n", mySOS, mySOS)
}
https://play.golang.org/p/nbWWEjHTzEX
This time mySOS contains the data I was expecting. However I still cannot see why the result of the initial code differs.
As previously stated I would be grateful if anyone can help clear up my obvious misunderstanding.