在 Go 语言里,方法和函数只差了一个,那就是方法在 func
和标识符之间多了一个参数。编程
type user struct { name string, email string, } //这是函数的定义 func notify(email string) { fmt.Println("Email is %s", email) } //这是方法的定义 func (u user) notify(email string) { fmt.Println("Email is %d", email) }
咱们能够看到,方法是在 func
和 notify
之间多了一个 user
类型的参数 u
,这个 u
就称做接收者。编程语言
为何有了函数,还须要方法?函数
Go 不是纯粹的面向对象编程语言,并且Go不支持类。所以,基于类型的方法是一种实现和类类似行为的途径。spa
相同的名字的方法能够定义在不一样的类型上,而相同名字的函数是不被容许的指针
接收者有两种,一种是值接收者,一种是指针接收者。顾名思义,值接收者,是接收者的类型是一个值,是一个副本,方法内部没法对其真正的接收者作更改;指针接收者,接收者的类型是一个指针,是接收者的引用,对这个引用的修改之间影响真正的接收者。像上面程序同样定义方法,将 user
改为 *user
就是指针接收者。code
package main import ( "fmt" ) type user struct { name string email string } func (u user)changeName(name string) { u.name = name } func (u *user) changeEmail(email string) { u.email = email } func main() { u1 := user{ "linlin", "11223@qq.com", } fmt.Println("name:",u1.name) u1.changeName("liming") fmt.Println("name:",u1.name) fmt.Println("email:",u1.email) u1.changeEmail("1221333333@qq.com") fmt.Println("email:",u1.email) }
结果为:对象
name: linlin name: linlin email: 11223@qq.com email: 1221333333@qq.com
注意:Go语言让咱们能够直接使用u1.changeName("liming")
。u1.changeName("liming")
会自动被Go语言解释为 (&u1).changeName("liming")
。blog
何时使用指针接收器,何时使用值接收器?string
通常来讲,指针接收器可使用在:对方法内部的接收器所作的改变应该对调用者可见时。面向对象编程
指针接收器也能够被使用在以下场景:当拷贝一个结构体的代价过于昂贵时。考虑下一个结构体有不少的字段。在方法内使用这个结构体作为值接收器须要拷贝整个结构体,这是很昂贵的。在这种状况下使用指针接收器,结构体不会被拷贝,只会传递一个指针到方法内部使用。
在其余的全部状况,值接收器均可以被使用。