go语言指针方法和值方法,引至string方法的思考

在公众号【Go语言中文网】中看到这样一篇面试题 https://mp.weixin.qq.com/s/9G3KQwXqQf56b8IQ7Tyysw

Example1

type Orange struct {
   Quantity int
}

func (o *Orange) Increase(n int) {
   o.Quantity += n
}

func (o *Orange) Decrease(n int) {
   o.Quantity -= n
}

func (o *Orange) String() string {
   return fmt.Sprintf("aaaa %#v", o.Quantity)
}

func main() {
   orange := &Orange{}
   orange.Increase(10)
   orange.Decrease(5)
   fmt.Println(orange)
}

先说明指针方法和值方法的区别:

指针方法:例如上述Increase方法,起引用类型为*Orange指针类型,如这种形式的引用所构造的方法为指针方法

值方法:方法的引用类型为正常类型,如func (o Orange) Decrease(n int){}这种形式为值方法

若方法都为值方法

Example2

type Orange struct {
   Quantity int
}

func (o Orange) Increase(n int) {
   o.Quantity += n
}

func (o Orange) Decrease(n int) {
   o.Quantity -= n
}

func (o Orange) String() string {
   return fmt.Sprintf("aaaa %#v", o.Quantity)
}

func main() {
   var orange Orange
   orange.Increase(10)
   orange.Decrease(5)
   fmt.Println(orange)
}

则会执行String方法里面输出5

若方法为指针方法

Example3

type Orange struct {
   Quantity int
}

func (o *Orange) Increase(n int) {
   o.Quantity += n
}

func (o *Orange) Decrease(n int) {
   o.Quantity -= n
}

func (o *Orange) String() string {
   return fmt.Sprintf("aaaa %#v", o.Quantity)
}

func main() {
   var orange Orange
   orange.Increase(10)
   orange.Decrease(5)
   fmt.Println(orange)
}

这种情况下不会执行string方法

这里是否会执行string方法,需要考虑一下为啥会执行String方法,最开始我看到这道题的时候,很疑惑为什么没有调用String方法,却会调用String方法,后来突然想到String方法是go原生的一个方法,调用时会默认执行该方法,当写了String方法时,覆盖了go的String方法,所以会默认执行该方法。了解了这个问题,下面开始说为什么Example3不会执行String方法,因为String的引用类型为指针类型,而orange为struct类型,默认不会执行,当orange定义为orange := &Orange,orange为指针类型,即类型的地址。