Home > Backend Development > Golang > Why Do I Need a Pointer Receiver to Append to a Slice in a Go Struct?

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

Mary-Kate Olsen
Release: 2024-12-27 17:39:12
Original
258 people have browsed it

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

Appending to Slice Properties in Go Structs

When attempting to append values to a slice property within a Go struct, you may encounter unexpected behavior if a specific call order is not followed. This article explores the reasons behind this issue and provides a solution.

In the code example provided, three methods are defined within different struct types to demonstrate the issue. Test1 and Test2 work as expected because their run() methods directly operate on the slice property. However, in Test3, the combo() method is called from run() using a value receiver instead of a pointer receiver.

Why a Pointer Receiver Is Required

In Go, all values are passed by value, meaning a copy of the passed value is created when calling a function or method. In the case of Test3, a copy of the Test3 value is made when combo() is called, and modifications to the slice property in this copy are not reflected in the original Test3 struct.

By using a pointer receiver, such as func (c *Test3) combo(), the original Test3 struct is directly modified, eliminating the issue of copy-local changes.

Solution

The solution is to change the receiver type of the combo() method to a pointer receiver. This ensures that the original Test3 struct is being modified by the method.

Updated Code

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())
}
Copy after login

Output

Test1 final: [0 1]
Test2 final: [0 1]
Test3 step 1 [0]
Test3 step 2 [0 1]
Test3 final: [0 1]
Copy after login

The above is the detailed content of Why Do I Need a Pointer Receiver to Append to a Slice in a Go Struct?. For more information, please follow other related articles on the PHP Chinese website!

source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Latest Articles by Author
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template