I want to sell my house and travel around the world, but the landlord refuses.
1. Slice parameter pass and for range assignment
1. Introduction
In this article we’ll talk about what happens when slice is passed as a parameter. And what happens when you iterate over assignments for range.
2. Slice the refs
package main
import "fmt"
func main() {
slice := []int{1, 2}
fmt.Printf("data:%v, len:%d, cap:%d\n", slice, len(slice), cap(slice))
updateslice(slice)
fmt.Printf("after data:%v, len:%d, cap:%d\n", slice, len(slice), cap(slice))
}
func updateslice(slice []int) {
slice[0] = 12
slice = append(slice, 10)
fmt.Printf("inner data:%v, len:%d, cap:%d\n", slice, len(slice), cap(slice))
}
Copy the code
Execution Result:
data:[1 2], len:2, cap:2
inner data:[12 2 10], len:3, cap:4
after data:[12 2], len:2, cap:2
Copy the code
Because a slice is a reference type, data modification affects the outside, which actually points to the same underlying data. However, after the append operation is performed on updateslice, it is found that the internal data modification does not affect the external variables. In this case, it can be seen that the internal slice capacity has been expanded, and the previous data will be copied to the new slice, and the expanded slice points to the new slice. The internal and external slices of the function do not point to the same underlying data.
Conclusion: When data adjustment is expanded, internal and external slices do not point to the same underlying data; Otherwise, it points to the same underlying array.
3. for range
type student struct { name string age int } func main() { m := make(map[string]*student) stus := []student{ {name: "The little prince", the age: 18}, {name: "na", the age: 23}, {name: "the big tortoise", the age: For _, stu := range STUS {m[stu.name] = &stu} for k, v := range m {FMT.Println(k, "=>", v.name) } }Copy the code
Our expected result for this code is
Naza => Prince Naza => Prince Naza => Prince NazaCopy the code
But here’s what you get:
The little prince => Prince Nazha => Prince Nazha => Prince Nazha => Prince Nazha => Prince NazhaCopy the code
The reason is that for traversal, the variable stu is a copy of the value, each traversal only copies the struct value, which points to the same address, so every operation m[stu.name] = &stu, actually points to the same address, after traversal, stores the copy of the last value of the structure.
The root cause is that for-range uses the same block of memory to receive the values in the loop.
That is, stu refers to the same address, but the value is copied, and everyone ends up referring to the same address.
Modified as follows:
For _, stu := range STUS {value := stu} m[stu.name] = &value}Copy the code
4. Summary
Slice transfer parameters we should pay attention to the scaling problem, no scaling, still the previous slice, or the new slice. Do not attempt to assign variables in the for range to other structures. This will result in references to the same data.
5. Pay attention to official accounts
Wechat official account: Stack Future
Hope you pay attention to ha, original is not easy, ask for praise, ask for attention, ask for share