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 <elitegobli...@gmail.com> 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+unsubscr...@googlegroups.com.
> 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.

Reply via email to