Decoding the Behavior of Go's Slice Range
In Go, slices are a versatile data structure that offers a dynamic array-like functionality. When iterating over a slice, the range syntax provides a convenient way to access its elements. However, certain scenarios may lead to unexpected behavior.
Consider the following code that creates a slice of student structs and populates a map with references to these structs:
type student struct { Name string Age int } func main() { m := make(map[string]*student) s := []student{ {Name: "Allen", Age: 24}, {Name: "Tom", Age: 23}, } for _, stu := range s { m[stu.Name] = &stu } fmt.Println(m) // map[Allen:0xc42006a0c0 Tom:0xc42006a0c0] }
The expected behavior is that the map should contain references to each individual student struct in the slice. However, the result shows that both keys in the map point to the same address.
This behavior can be explained by understanding that the stu variable in the range loop is a copy of the slice element, not a reference. The stu.Name retrieves a copy of the name field, and &stu takes the address of the copy, resulting in the same address for all map values.
To correct this issue, the code should take the address of the actual slice element instead:
for i := range s { m[s[i].Name] = &s[i] }
By accessing the slice element directly, we obtain a reference to its unique memory location, resolving the unexpected behavior and ensuring that the map contains references to each student struct.
The above is the detailed content of Why Does Go's Slice Range Loop Create Unexpected Behavior When Used with Maps?. For more information, please follow other related articles on the PHP Chinese website!