A curious issue arose in a project involving Go pointers. The problem was that when converting a slice of struct objects to a slice of interfaces, the first pointer's memory address was repeatedly used in the output.
To resolve this issue, the developer modified the conversion function to use an extra variable, which yielded the expected output.
This raises the question: why did the original solution fail? To understand this, we need to delve into how Go handles pointers and slices.
In Go, the expression *coll returns a slice header containing information about the underlying array, its length, and its capacity. When accessing an element of a slice, the expression (*coll)[idx] is used, which returns a reference to the element at index idx.
In the original solution, item was the loop variable in the range *coll loop. This loop iterates over the slice header, assigning each element of the slice to the loop variable item. However, since item is the loop variable, its memory address remains the same throughout the loop. Therefore, when &item is appended to the output slice, the same memory address is added multiple times, resulting in the observed behavior.
The revised solution uses the expression i := (*coll)[idx] within the loop to assign the element at index idx to a local variable i. This variable has a distinct memory address from the loop variable item, and thus, when &i is added to the output slice, each element has a different memory address.
To illustrate the difference in memory addresses between the loop variable and the element being accessed, consider the following code:
package main import "fmt" func main() { coll := []int{5, 10, 15} for i, v := range coll { fmt.Printf("This one is always the same; %v\n", &v) fmt.Println("This one is 4 bytes larger each iteration; %v\n", &coll[i]) } }
Running this code will demonstrate that &v has the same memory address for all iterations of the loop, while &coll[i] has a different memory address for each iteration.
The above is the detailed content of Why Does Direct Slice Conversion in Go Reuse the Same Memory Address for Pointers?. For more information, please follow other related articles on the PHP Chinese website!