Go语言中有着面向对象的思想,当我们创建了一个类型之后,可以给这个类型添加不同的方法,给类型添加方法的方式类似于创建一个函数,只是在func和函数名中添加一个(类型名 类型)。这个东西就是所谓的接收者,也就是类型作为接收者接收该函数为自己的方法。有时候我们希望可以更改类型中成员变量的值,而有时候我们不希望类型中成员变量的值被改变。这就是Golang中使用值接收者与指针接收者的区别。
一个例子语言叙述比较繁琐,直接看这个简单的例子:
package main
import "fmt"
type user struct {
name string
email string
}
func (u user) changeEmail0(NewEmail string) {
u.email = NewEmail
fmt.Println("changeEmail0: userName is ",u.name," userEmail is ",u.email)
}
func (u *user) changeEmail1(NewEmail string) {
u.email = NewEmail
fmt.Println("changeEmail1: userName is ",u.name," userEmail is ",u.email)
}
func main() {
usr0 := &user{"pf", "xxxxxxxxx@qq.com"}
usr0.changeEmail0("xxxxxxxxx@163.com")
fmt.Println("main: userName is ",usr0.name," userEmail is ",usr0.email)
usr1 := &user{"pf", "xxxxxxxxx@qq.com"}
usr1.changeEmail1("xxxxxxxxx@163.com")
fmt.Println("main: userName is ",usr1.name," userEmail is ",usr1.email)
}
func (u user) changeEmail0(NewEmail string)func (u *user) changeEmail1(NewEmail string)
changeEmail0: userName is pf userEmail is xxxxxxxxx@163.com
main: userName is pf userEmail is xxxxxxxxx@qq.com
changeEmail1: userName is pf userEmail is xxxxxxxxx@163.com
main: userName is pf userEmail is xxxxxxxxx@163.com
可以看出值接收者与指针接收者的区别。
总结使用值接收者还是指针接收者,不应该由该方法是否修改了接收到的值来决定。这个决策应该基于该类型的本质。简单来说,如果给这个类型增加或者删除某个值,是需要创建一个新值,则选择值接收者。如果要修改当前的值,则选择指针接收者。