package main
import "fmt"
type user struct {
name string
email 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语言既允许使用值,也允许使用指镇上来调用方法,不必严格符合接收者的类型。应该使用值接收者,还是应该使用指针接收者,这个问题有时会比较迷惑人。