首先,我们定义如下结构体:
package main
import "fmt"
// 值接收者与指针接收者的区别
type sInterface interface {
info()
debug()
}
type Str struct {
lg string
}
func (s Str) info() {
fmt.Println("info:lg value is", s.lg)
}
func (s *Str) debug() {
fmt.Println("debug:lg value is", s.lg)
}
func main() {
s := Str{"go"}
s.info()
s.debug()
// output
//info:lg value is go
//debug:lg value is go
}
通过上面的示例,可以看出结构体的实例是一个值类型,在接收者是指针的方法中,依然可以访问到该值。这是因为实现了接收者是值类型的方法,相当于自动实现了接收者是指针类型的方法。反之,实现了接收者是指针类型的方法,不会自动实现接收者是值类型的方法。
换句话说,在实现了info()方法,默认就实现了debug()方法。反之,实现了debug()方法,不会自动实现info()方法。
首先要知道指针类型的接收者,有如下两个优点:
方法的接收者使用值类型还是指针类型,并不是由是否修改接收者的值决定的,应该是由接收者的类型决定。方法的接收者如果是原始类型,推荐使用值类型。方法的接收者如果是非原始类型,推荐使用指针类型。
这里的原始类型可以理解为Go语言内置的原始类型,如数值类型、字符串类型、切片等等。非原始类型可以理解为自定义的接收者。