package mainimport "fmt"type user struct {name stringemail string}//notify使用值接收者实现了一个方法func (u user)notify() {fmt.Printf("Sending User Email To %s<%s>\n",u.name,u.email)}//changeEmail使用指针接收者实现了一个方法func (u *user)changeEmail(email string) {u.email = email}func main() {/*user类型的值可以用来调用使用值接收者声明的方法*/bill := user{"Bill","bill@email.com"}bill.notify()/*指向user类型值的指针也可以用来调用使用值接收者声明的方法*/lisa := &user{"Lisa","lisa@email.com"}lisa.notify()/*user类型的值可以用来调用使用指针接收者声明的方法*/bill.changeEmail("bill@newdomain.com")bill.notify()/*指向user类型值的指针也可以用来调用使用值接收者声明的方法*/lisa.changeEmail("lisa@newdomain.com")lisa.notify()}
当bil(user类型值变量)调用使用值接收者方法时,调用时会使用这个值的一个副本来执行。
当lisa(一个指向user类型值的指针)调用值接收者方法时,底层会把指针解引用为值:(*lisa).notify()
当bill(user类型值变量)调用使用指针接收者声明的方法时,首先引用bill值得到一个指针,这样这个指针就能够匹配方法的接收者类型,再进行调用:(&bill).changeEmail ("bill@newdomain.com")
总结一下,值接收者使用值的副本来调用方法,而指针接收者使用实际值来调用方法
Go语言既允许使用值,也允许使用指镇上来调用方法,不必严格符合接收者的类型。应该使用值接收者,还是应该使用指针接收者,这个问题有时会比较迷惑人。
