首页 > 后端开发 > Golang > 为什么在 Go 中向切片追加指针会导致意外的值被覆盖?

为什么在 Go 中向切片追加指针会导致意外的值被覆盖?

Barbara Streisand
发布: 2024-12-15 09:24:10
原创
498 人浏览过

Why Does Appending Pointers to a Slice in Go Result in Unexpected Overwritten Values?

奇怪的 Golang“追加”行为:覆盖切片中的值

在 Golang 中,追加到切片时,了解其区别非常重要指针类型和非指针类型之间。

考虑这个例子code:

import "fmt"

type Foo struct {
    val int
}

func main() {
    var a = make([]*Foo, 1)
    a[0] = &Foo{0}

    var b = [3]Foo{Foo{1}, Foo{2}, Foo{3}}
    for _, e := range b {
        a = append(a, &e)
    }

    for _, e := range a {
        fmt.Printf("%v ", *e)
    }
}
登录后复制

预期输出为 {0} {1} {2} {3},但实际打印为 {0} {3} {3} {3}。这是因为 for 循环对数组元素的副本进行操作。

使用 for ... range 进行迭代时,会创建一个临时循环变量并为其分配数组元素的值。在本例中,临时变量的类型为 Foo。但是,当追加到切片时,会添加临时变量的地址,而不是实际数组元素的地址。

在每次循环迭代中,该临时变量都会被覆盖为数组最后一个元素的值数组,即 Foo{3}。因此,切片包含对同一指针的多个引用,指向数组的最后一个元素。

要解决此问题,应附加数组元素的地址而不是循环变量:

for i := range b {
    a = append(a, &b[i])
}
登录后复制

通过此修改,输出如预期:{0} {1} {2} {3}。

此行为突出了理解的重要性Go 的类型系统以及使用切片时指针和非指针的区别。

以上是为什么在 Go 中向切片追加指针会导致意外的值被覆盖?的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板