首页 > 后端开发 > Golang > 为什么在 Go `for...range` 循环中添加指针会产生意外结果?

为什么在 Go `for...range` 循环中添加指针会产生意外结果?

Barbara Streisand
发布: 2024-12-30 17:03:12
原创
772 人浏览过

Why Does Appending Pointers in a Go `for...range` Loop Produce Unexpected Results?

理解Go中append的奇怪行为

在Go中,append函数对切片进行操作以添加新元素。但是,在 for range 循环中将指针附加到数组中的元素时,用户可能会遇到意外行为。

请考虑以下示例:

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 range 循环迭代元素的副本,而不是原始元素本身。在这种情况下,循环变量 e 保存数组当前元素的副本。附加切片时,会添加循环变量的地址,该地址为所有迭代引用相同的内存位置。因此,当遇到数组的最后一个元素时,所有附加地址都指向同一个元素。

修复

要解决此问题,append 函数应该是与原始数组元素的地址一起使用,而不是与循环变量一起使用。以下是更正后的代码:

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

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

结论

理解 Go 中指针和非指针类型之间的区别对于正确处理内存引用至关重要。使用 for range 循环时,必须考虑是否需要访问原始元素还是副本,并相应地使用适当的语法。

以上是为什么在 Go `for...range` 循环中添加指针会产生意外结果?的详细内容。更多信息请关注PHP中文网其他相关文章!

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