首页 > 后端开发 > Golang > 为什么我需要一个指针接收器来附加到 Go 结构中的切片?

为什么我需要一个指针接收器来附加到 Go 结构中的切片?

Mary-Kate Olsen
发布: 2024-12-27 17:39:12
原创
258 人浏览过

Why Do I Need a Pointer Receiver to Append to a Slice in a Go Struct?

附加到 Go 结构中的切片属性

尝试将值附加到 Go 结构中的切片属性时,您可能会遇到意外行为如果未遵循特定的调用顺序。本文探讨了此问题背后的原因并提供了解决方案。

在提供的代码示例中,在不同的结构类型中定义了三个方法来演示该问题。 Test1 和 Test2 按预期工作,因为它们的 run() 方法直接对切片属性进行操作。但是,在 Test3 中,使用值接收器而不是指针接收器从 run() 调用组合()方法。

为什么需要指针接收器

在 Go 中,所有值都是按值传递,这意味着在调用函数或方法时会创建传递值的副本。在 Test3 的情况下,调用combo() 时会创建 Test3 值的副本,并且对该副本中的 slice 属性的修改不会反映在原始 Test3 结构中。

通过使用指针接收器,如func(c *Test3)combo(),直接修改原来的Test3结构体,消除了copy-local的问题

解决方案

解决方案是将combo()方法的接收者类型更改为指针接收者。这确保原始 Test3 结构体被该方法修改。

更新的代码

package main

import (
  "fmt"
)

type Test1 struct {
  all []int
}

func (c Test1) run() []int {
  for i := 0; i < 2; i++ {
    c.all = append(c.all, i)
  }
  return c.all
}

var gloabl_all []int

type Test2 struct {}

func (c Test2) run() []int {
  c.combo()
  return gloabl_all
}

func (c Test2) combo() {
  for i := 0; i < 2; i++ {
    gloabl_all = append(gloabl_all, i)
  }
}

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() {
  test1 := &Test1{}
  fmt.Println("Test1 final:", test1.run())

  test2 := &Test2{}
  fmt.Println("Test2 final:", test2.run())

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

输出

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

以上是为什么我需要一个指针接收器来附加到 Go 结构中的切片?的详细内容。更多信息请关注PHP中文网其他相关文章!

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