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!