Please can you help me understand how generating a slice from an array works. Why are ID1 and ID2 not the same?
a := [2]string{"a", "b"}
b := [2]string{"c", "d"}
var z [2][2]string
z[0] = a
z[1] = b
fmt.Printf("%s\n", z)
var id [][]string
for _, t := range z {
temp := t[:]
id = append(id, temp)
}
fmt.Printf("\nid1 = %s", id)
var id2 [][]string
for _, t := range z {
temp := t
id2 = append(id2, temp[:])
}
fmt.Printf("\nid2 = %s", id2)
[[ab] [cd]]
id1 = [[cd] [cd]]
id2 = [[ab] [cd]]
Because the for range
loop has a single iteration variable which is reused in each iteration. Spec: For statements: For statements with for clause
Variables declared by the init statement are re-used in each iteration.
So in your first loop:
for _, t := range z {
temp := t[:]
id = append(id, temp)
}
There is a single t
, and you slice the same t
array, so each temp
slice you append, it will point to the same backing array, which is t
, and it is overwritten in each iteration, so its value will be the value of the last iteration: [cd]
.
In your second loop:
for _, t := range z {
temp := t
id2 = append(id2, temp[:])
}
Also there is a single t
iteration variable, but you make a copy of it: temp := t
, and you slice this copy, which is detached from t
, and you append a slice that has the copy as its backing array, which will not be overwritten in each iteration.
This is the problematic assignment. It is not what it seems:
temp := t[:]
Here, t
is an array and the loop variable. That means at each iteration, the contents of the current array is copied onto t
. At the first iteration, t=[]string{"a","b"}
, and a slice is created to point to this array and assigned to temp
. At the second iteration t
is overwritten to become []string{"c","d"}
. This operation also overwrites the contents of the first slice. So, you end up with the {{"c","d"},{"c","d"}}
. The important point here is that contents of t
gets overwritten, and t
is shared between the two slices.
In the first loop you are saving slices which have the same backing array (ie. the loop variable t
). In the second loop you are storing slices using different backing arrays since you make a copy of t
in temp
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.