On Wednesday, November 21, 2018 at 2:38:42 PM UTC-8, Sun Frank wrote: > > Perfect! Thank you so much for your answer and explanation, : ) >
It is, unfortunately, a very common "gotcha". More discussion can be found here: https://github.com/golang/go/issues/20733 Cheers, -Sam. > Best Regards > > Mail : eliteg...@gmail.com <javascript:> > Mobile : 0422 118 452 > TechBlog : http://elitegoblin.github.io > GitHub : http://github.com/eliteGoblin/ > > > andrey mirtchovski <mirtc...@gmail.com <javascript:>> 于2018年11月22日周四 > 上午9:22写道: > >> this is a case of a variable being reused during a range loop. >> essentially k[:] is optimized to something resembling &k (a pointer to >> the memory location of the backing array) which is appended as such to >> the [][]int variable. the next iteration it is the same variable in >> memory, however it's pointing to a different backing array. the >> address of that variable is added to [][]int again. in order to avoid >> this you will have to redeclare k inside the loop to ensure a new >> backing array is used when adding to the slice of slices. >> >> maybe the easiest way to explain this is to point you towards this >> blog post: https://blog.golang.org/go-slices-usage-and-internals and >> to note that the for loop in your example expands/unrolls to something >> like this, which breaks what you considered to "work" in your original >> example: >> >> a1 := [3]int{1, 2, 3} >> a2 := [3]int{4, 5, 6} >> a3 := [3]int{7, 8, 9} >> >> s := make([][]int, 0) >> a := a1 >> s = append(s, a[:]) >> a = a2 >> s = append(s, a[:]) >> a = a3 >> s = append(s, a[:]) >> >> fmt.Println(s) >> On Wed, Nov 21, 2018 at 2:41 PM Sun Frank <eliteg...@gmail.com >> <javascript:>> wrote: >> > >> > Hi guys, I came across some code that surprised me, but I could not >> figured out why it behave like this, >> > >> > s := make([][]int, 0) >> > a1 := [3]int{1, 2, 3} >> > a2 := [3]int{4, 5, 6} >> > s = append(s, a1[:]) >> > s = append(s, a2[:]) >> > fmt.Println(s) >> > >> > mp := make(map[[3]int]bool) >> > mp[[3]int{1, 2, 3}] = true >> > mp[[3]int{4, 5, 6}] = true >> > mp[[3]int{7, 8, 9}] = true >> > res := make([][]int, 0) >> > for k := range mp { >> > fmt.Printf("key is %+v\n", k[:]) >> > res = append(res, k[:]) >> > fmt.Printf("after append: %+v\n", res) >> > } >> > >> > or on playground >> > >> > the output is: >> > >> > [[1 2 3] [4 5 6]] // this is as expected >> > key is [1 2 3] >> > after append: [[1 2 3]] >> > key is [4 5 6] >> > after append: [[4 5 6] [4 5 6]] // Why it get this not [[1 2 3] [4 5 >> 6]] >> > key is [7 8 9] >> > after append: [[7 8 9] [7 8 9] [7 8 9]] // why even this? >> > >> > >> > any thoughts? >> > >> > >> > Thanks! >> > >> > >> > >> > -- >> > You received this message because you are subscribed to the Google >> Groups "golang-nuts" group. >> > To unsubscribe from this group and stop receiving emails from it, send >> an email to golang-nuts...@googlegroups.com <javascript:>. >> > For more options, visit https://groups.google.com/d/optout. >> > -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.