首页 >后端开发 >Golang >为什么从具有范围循环的 Go 切片进行复制有时会重复内存地址?

为什么从具有范围循环的 Go 切片进行复制有时会重复内存地址?

Linda Hamilton
Linda Hamilton原创
2024-12-23 19:17:15987浏览

Why Does Copying from a Go Slice with a Range Loop Sometimes Duplicate Memory Addresses?

在 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中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn