首页 > 后端开发 > Golang > 为什么除非使用指针接收器,否则附加到 Golang 结构体方法中的切片不起作用?

为什么除非使用指针接收器,否则附加到 Golang 结构体方法中的切片不起作用?

Linda Hamilton
发布: 2024-12-31 15:09:10
原创
441 人浏览过

Why doesn't appending to a slice within a Golang struct method work unless a pointer receiver is used?

为什么我不能追加到 Golang 中结构体属性的切片?

在 Golang 中,一切都是按值传递的,这意味着只要将对象作为参数传递给函数,就会创建对象的副本。当尝试附加到作为结构体属性的切片时,这可能会导致意外行为。

问题:Test3

考虑以下示例:

package main

import "fmt"

type Test3 struct {
    all []int
}

func (c Test3) run() []int {
    c.combo()
    return c.all
}

func (c Test3) combo() {
    for i := 0; i < 2; i++ {
        c.all = append(c.all, i)
        fmt.Println("Test3 step", i+1, c.all)
    }
}

func main() {
    test3 := &Test3{}
    fmt.Println("Test3 final:", test3.run())
}
登录后复制

当您调用 test3.run() 时,它会创建 test3 的副本并将其传递给运行。 run 方法然后调用combo,它将两个值附加到c.all。但是,当 run 返回时,对 c.all 的更改会丢失,因为 test3 的副本被丢弃。这会导致返回空切片,如输出所示:

Test3 step 1 [0]
Test3 step 2 [0 1]
Test3 final: []
登录后复制

解决方案:使用指针接收器

要解决此问题,您需要将指针接收器用于组合方法。这告诉编译器传递指向 Test3 值的指针而不是副本。

func (c *Test3) combo() {
    for i := 0; i < 2; i++ {
        c.all = append(c.all, i)
        fmt.Println("Test3 step", i+1, c.all)
    }
}
登录后复制

使用指针接收器,对组合中的 c.all 所做的更改将直接应用于原始 Test3 值,因为它是通过引用传递的。这会产生正确的输出:

Test3 step 1 [0]
Test3 step 2 [0 1]
Test3 final: [0 1]
登录后复制

通过理解按值传递的概念并适当使用指针接收器,您可以在使用 Golang 结构体中的切片时避免意外行为。

以上是为什么除非使用指针接收器,否则附加到 Golang 结构体方法中的切片不起作用?的详细内容。更多信息请关注PHP中文网其他相关文章!

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