package main
import (
"fmt"
)
func main() {
values := make([]int, 0, 100)
val := make([][]int, 2)
for i:=0; i<2; i++ {
values = values[:0]
for j:=0; j<2; j++ {
values = append(values, i+j)
}
val[i] = values
fmt.Println(values, val) //
}
fmt.Println(val)
}
https://play.golang.org/p/5x60VfDXbFw
when appending slice,val is expected to be [[0, 1], [1, 2]], but got [[1,2], [1,2]]
This happens because the slice val
contains pointers to its subslices, rather than the subslices themselves. In your code, you initially place a pointer to values
in positions val[0]
. Then you modify values
and then set a pointer to values
in val[1]
. But both val[0]
and val[1]
point to the same underlying object (values
), which has been modified.
You can fix this by creating a new values
slice on each iteration of the outer loop, this way each sub slice of val
will be a different slice.
For example:
func main() {
val := make([][]int, 2)
for i:=0; i<2; i++ {
values := make([]int, 0, 100)
for j:=0; j<2; j++ {
values = append(values, i+j)
}
val[i] = values
fmt.Println(values, val) //
}
fmt.Println(val)
}
Output from fmt.Println
:
[0 1] [[0 1] []] // values, val
[1 2] [[0 1] [1 2]] // values, val
[[0 1] [1 2]] // val
You should initialize values in your for loop, values = []int{}
code like this:
package main
import (
"fmt"
)
func main() {
var (
valLength = 2
)
val := make([][]int, valLength)
for i := 0; i < valLength; i++ {
values := []int{}
for j := 0; j < 2; j++ {
values = append(values, i+j)
}
val[i] = values
fmt.Println(values, val) //
}
fmt.Println(val)
}
And you only change variable valLength
to get any length of slice you want.
slice feature in go:
Slices hold references to an underlying array, and if you assign one slice to another, both refer to the same array.
The value of slice will be the last time you modify it. Thus, here's two approach to achieve the goal.
use copy
func main() {
values := make([]int, 0, 100)
val := make([][]int, 2)
for i := 0; i < 2; i++ {
values = values[:0]
for j := 0; j < 2; j++ {
values = append(values, i+j)
}
val[i] = make([]int, 2)
copy(val[i], values)
fmt.Println(values, val) //
}
fmt.Println(val)
}
new values slice in first for-loop each time
val := make([][]int, 2)
for i := 0; i < 2; i++ {
values := make([]int, 0, 2)
for j := 0; j < 2; j++ {
values = append(values, i+j)
}
val[i] = values
fmt.Println(values, val) //
}