Home  >  Article  >  Backend Development  >  Go Pointers: Value vs. Pointer Receivers - Does it Matter?

Go Pointers: Value vs. Pointer Receivers - Does it Matter?

Barbara Streisand
Barbara StreisandOriginal
2024-11-07 17:51:02909browse

Go Pointers: Value vs. Pointer Receivers - Does it Matter?

Go Pointers: A Closer Look at Value and Pointer Receivers

In Go, pointers play a crucial role in effectively managing memory and creating reusable data structures. Beginners often grapple with the concept of pointers, especially as it differs from languages like C/C . This article aims to clarify the nuances of Go pointers and address common misconceptions.

Consider the code snippet below, borrowed from the Go Tour #52:

type Vertex struct {
    X, Y float64
}

func (v *Vertex) Abs() float64 {
    return math.Sqrt(v.X*v.X + v.Y*v.Y)
}

func main() {
    v := &Vertex{3, 4}
    fmt.Println(v.Abs())
}

Here, we define a struct Vertex, and a method Abs which calculates the absolute value of a vertex. The receiver v of Abs is a pointer to Vertex. This means that Abs operates on pointers to vertices, allowing for modifications to the original vertex.

Now, let's consider a slight modification to the code:

func (v Vertex) Abs() float64 {
    return math.Sqrt(v.X*v.X + v.Y*v.Y)
}

Interestingly, this modification leads to the same result. Our question arises: is there a difference between using a *Vertex or Vertex as the receiver for Abs?

The answer lies in two fundamental rules of Go:

  1. Value and Pointer Receiver Conversion: Go allows deriving a method with a pointer receiver from one with a value receiver. Thus, func (v Vertex) Abs() float64 automatically generates an additional implementation:

    func (v Vertex) Abs() float64 { return math.Sqrt(v.X*v.X+v.Y*v.Y) }
    func (v *Vertex) Abs() float64 { return Vertex.Abs(*v) }  // GENERATED METHOD

    The compiler seamlessly finds the generated method, explaining why v.Abs() still works even though v is not a pointer.

  2. Automatic Address Taking: Go can automatically take the address of a variable. This means when calling v.Abs() in the modified code without the pointer receiver, it's equivalent to:

    vp := &v
    vp.Abs()

    Thus, the function still receives a pointer to the vertex, regardless of whether we explicitly use &.

The above is the detailed content of Go Pointers: Value vs. Pointer Receivers - Does it Matter?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
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