在 Go 中从切片复制时重用内存地址
您在 Go 中遇到了一种奇怪的行为,即使用范围从切片复制值循环导致输出中出现重复的内存地址。为了解决这个问题,您修改了代码以创建一个临时变量,该变量产生了预期的不同地址。
出现此行为是因为在原始代码中,循环变量项是指向切片当前元素的指针。当您迭代切片时,Go 会重用此指针变量,在每次迭代时更改其值,但保持相同的内存地址。因此,当您将 &item 分配给输出切片时,您会无意中多次重复相同的内存地址。
为了防止这种重用,修改后的代码会创建一个临时变量 i 来保存当前元素的副本。这迫使 Go 为每次迭代创建新的内存分配,从而在输出切片中产生唯一的地址。
为了说明这个概念,请考虑以下示例:
package main import "fmt" type Region struct { Name string } func main() { // Create a slice of Region objects. regions := []Region{ {Name: "Central"}, {Name: "East"}, } // Original code - duplicates memory addresses fmt.Println("Original Code:") models1 := make([]Model, len(regions)) for idx, item := range regions { models1[idx] = &item } for _, m := range models1 { fmt.Println(m) } // Modified code - generates unique memory addresses fmt.Println("Modified Code:") models2 := make([]Model, len(regions)) for idx, _ := range regions { i := regions[idx] models2[idx] = &i } for _, m := range models2 { fmt.Println(m) } }
运行此代码,您会注意到原始代码打印重复的内存地址,而修改后的代码产生唯一的地址。
以上是为什么从具有范围循环的 Go 切片进行复制有时会重复内存地址?的详细内容。更多信息请关注PHP中文网其他相关文章!