Considerations for range in golang in slice and map traversal
- 2020-06-23 00:40:19
- OfStack
Considerations for range in slice and map traversal in golang
package main
import (
"fmt"
)
func main() {
slice := []int{0, 1, 2, 3}
myMap := make(map[int]*int)
for _,v :=range slice{
if v==1 {
v=100
}
}
for k,v :=range slice{
fmt.Println("k:",k,"v:",v)
}
}
The expected results should be:
[
k: 0 v: 0
k: 1 v: 100
k: 2 v: 2
k: 3 v: 3
Pit, but actually
[
k: 0 v: 0
k: 1 v: 1
k: 2 v: 2
k: 3 v: 3
The value of slice has not changed. The reason for the above problem is that the traversal of for range is a copy of the original content, so it cannot be used to modify the content in the original slice.
Use k to modify values directly from the index.
for k,v :=range slice{
if v==1 {
slice[k]=100
}
}
The other one
package main
import (
"fmt"
)
func main() {
s :=[]int{1,2,3,4}
m :=make(map[int]*int)
for k,v:=range s{
m[k]=&v
}
for key, value := range m {
fmt.Printf("map[%v]=%v\n", key, *value)
}
fmt.Println(m)
}
The expected value to be printed should be:
[
map[0]=1
map[1]=2
map[2]=3
map[3]=4
Actual results:
[
map[2]=4
map[3]=4
map[0]=4
map[1]=4
As we can guess from the above results, range points to the same pointer. With Println we can verify our conjecture
map[1:0xc00008a000 2:0xc00008a000 3:0xc00008a000 0:0xc00008a000]
We can see that our guess is correct
Or because actually for range create copies of each element, rather than directly back to each element of reference, if you use the value variable address as a pointer to each element, can lead to errors, in an iterative, return variable is an iterative process, according to a new variable section assignment in turn so value address is always the same, lead to the results than expected.
Declare an intermediate variable, save value, and copy to map
package main
import (
"fmt"
)
func main() {
s :=[]int{1,2,3,4}
m :=make(map[int]*int)
for k,v:=range s{
n:=v
m[k]= &n
}
for key, value := range m {
fmt.Printf("map[%v]=%v\n", key, *value)
}
fmt.Println(m)
}
conclusion