Go 语言可以给自定义的类型添加一个方法。这里的方法其实也是函数,跟函数的区别在于在 func
关键字和函数名中间增加了一个参数,可以认为该类型也作为了参数传递入了函数中,例:文章源自编程技术分享-https://mervyn.life/11b854dc.html
package main
import "fmt"
type Person struct {
name string
age int
}
//值接收者
func (p Person) sayHello() {
fmt.Println(p.name)
}
//引用接收者
func (p *Person) setName(name string) {
p.name = name
}
func main() {
p := Person{name: "mervyn"}
p.sayHello()
p.setName("tz")
p.sayHello()
}
- 值接收者声明的方法,调用时传递的是这个值的一个副本。
- 引用接收者声明的方法,在调用者会共享调用方法时接收者所指向的值。
注意:值类型的接收者也可以使用指针类型的调用。例:文章源自编程技术分享-https://mervyn.life/11b854dc.html
p := &Person{name: "mervyn"}
(*p).sayHello()
所以有如下的对照关系:文章源自编程技术分享-https://mervyn.life/11b854dc.html
方法接收者 | 实际可用类型 |
---|---|
(t T) | T and *T |
(t *T) | *T |
因此在如下的代码执行时,会报错,因为interface
声明了notify
方法,而方法接收者使用的是指针类型,因而只有*user
实现了notify
方法,user
并没有实现,所以sendNotification的参数应该是&u,而不是u。文章源自编程技术分享-https://mervyn.life/11b854dc.html
package main
import (
"log"
)
type notifier interface {
notify()
}
type user struct {
name string
email string
}
func (u *user) notify() {
log.Printf("Sending user email to %s", u.name)
}
func main() {
u := user{"Bill", "bill@email.com"}
sendNotification(u)
}
func sendNotification(n notifier) { //注意此处传递的参数类型
n.notify()
}
执行结果文章源自编程技术分享-https://mervyn.life/11b854dc.html
# command-line-arguments
./main.go:23: cannot use u (type user) as type notifier in argument to sendNotification:
user does not implement notifier (notify method has pointer receiver)
文章源自编程技术分享-https://mervyn.life/11b854dc.html 我的微信公众号
微信扫一扫
评论