Home >Backend Development >Golang >Why Does Using Pointer Receivers in Go Interface Implementations Require Returning Pointers?

Why Does Using Pointer Receivers in Go Interface Implementations Require Returning Pointers?

DDD
DDDOriginal
2024-12-12 11:35:11734browse

Why Does Using Pointer Receivers in Go Interface Implementations Require Returning Pointers?

Pointer Receivers in Golang and Interface Implementation

In Go, receiver functions allow methods to operate on specific types. When a method has a pointer receiver, it can modify the actual instance of the struct.

Understanding the Issue

Consider the following code snippet:

type IFace interface {
    SetSomeField(newValue string)
    GetSomeField() string
}

type Implementation struct {
    someField string
}

// Method with non-pointer receiver
func (i Implementation) GetSomeField() string {
    return i.someField
}

// Method with non-pointer receiver
func (i Implementation) SetSomeField(newValue string) {
    i.someField = newValue
}

In this code, both methods have non-pointer receivers. This means that when calling SetSomeField, it creates a copy of the struct and modifies that copy. The original instance remains unchanged.

Using a Pointer Receiver

To change the actual instance, the SetSomeField method should have a pointer receiver:

// Method with pointer receiver
func (i *Implementation) SetSomeField(newValue string) {
    i.someField = newValue
}

Now, SetSomeField can modify the original instance. However, this raises an issue when implementing the IFace interface:

package main

import (
    "fmt"
)

type IFace interface {
    SetSomeField(newValue string)
    GetSomeField() string
}

type Implementation struct {
    someField string
}

// Method with pointer receiver
func (i *Implementation) GetSomeField() string {
    return i.someField
}

// Method with pointer receiver
func (i *Implementation) SetSomeField(newValue string) {
    i.someField = newValue
}

func Create() IFace {
    obj := Implementation{someField: "Hello"}
    return obj // Offending line
}

func main() {
    a := Create() // Assigning an Implementation value to an IFace variable
    a.SetSomeField("World") // Will panic because a is an Implementation value, not a pointer
    fmt.Println(a.GetSomeField())
}

Compiling this code results in a panic because Create returns a Implementation value, not a pointer to it. To implement the interface with a pointer receiver, the method must be declared as a pointer receiver and the Create function must return a pointer to Implementation.

type IFace interface {
    SetSomeField(newValue string)
    GetSomeField() string
}

type Implementation struct {
    someField string
}

// Method with pointer receiver
func (i *Implementation) GetSomeField() string {
    return i.someField
}

// Method with pointer receiver
func (i *Implementation) SetSomeField(newValue string) {
    i.someField = newValue
}

func Create() *Implementation {
    obj := Implementation{someField: "Hello"}
    return &obj
}

func main() {
    var a IFace
    a = Create() // Now assigning a pointer to Implementation to an IFace variable
    a.SetSomeField("World")
    fmt.Println(a.GetSomeField())
}

Now, a is a pointer to an Implementation value, which implements IFace with pointer receivers. Changes made through SetSomeField will affect the original instance.

The above is the detailed content of Why Does Using Pointer Receivers in Go Interface Implementations Require Returning Pointers?. 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