Golang 中的指针接收器和接口实现
在 Go 中,接收器函数允许方法对特定类型进行操作。当方法具有指针接收器时,它可以修改结构体的实际实例。
理解问题
考虑以下代码片段:
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 }
在此代码中,两种方法都有非指针接收器。这意味着当调用 SetSomeField 时,它会创建该结构的副本并修改该副本。原始实例保持不变。
使用指针接收器
要更改实际实例,SetSomeField 方法应该有一个指针接收器:
// Method with pointer receiver func (i *Implementation) SetSomeField(newValue string) { i.someField = newValue }
现在,SetSomeField 可以修改原始实例了。然而,这在实现 IFace 接口时会引发一个问题:
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()) }
编译此代码会导致恐慌,因为 Create 返回一个 Implement 值,而不是指向它的指针。要使用指针接收器实现接口,必须将方法声明为指针接收器,并且 Create 函数必须返回指向 Implements 的指针。
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()) }
现在,a 是指向 Implements 值的指针,它使用指针接收器实现 IFace。通过 SetSomeField 所做的更改将影响原始实例。
以上是为什么在 Go 接口实现中使用指针接收器需要返回指针?的详细内容。更多信息请关注PHP中文网其他相关文章!