Go 方法指针接收者和值接收者

mervyn 2019年3月31日14:09:38编程语言 GoGo 方法指针接收者和值接收者已关闭评论27

Go 语言可以给自定义的类型添加一个方法。这里的方法其实也是函数,跟函数的区别在于在 func 关键字和函数名中间增加了一个参数,可以认为该类型也作为了参数传递入了函数中,例:文章源自Mervyn's Blog-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()
}
  • 值接收者声明的方法,调用时传递的是这个值的一个副本。
  • 引用接收者声明的方法,在调用者会共享调用方法时接收者所指向的值。

注意:值类型的接收者也可以使用指针类型的调用。例:文章源自Mervyn's Blog-https://mervyn.life/11b854dc.html

p := &Person{name: "mervyn"}
(*p).sayHello()

所以有如下的对照关系:文章源自Mervyn's Blog-https://mervyn.life/11b854dc.html

方法接收者 实际可用类型
(t T) T and *T
(t *T) *T

因此在如下的代码执行时,会报错,因为interface声明了notify方法,而方法接收者使用的是指针类型,因而只有*user实现了notify方法,user并没有实现,所以sendNotification的参数应该是&u,而不是u。文章源自Mervyn's Blog-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()
}

执行结果文章源自Mervyn's Blog-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)
文章源自Mervyn's Blog-https://mervyn.life/11b854dc.html
weinxin
我的微信公众号
微信扫一扫
mervyn
Go语言学习(十一)| 通道 编程语言

Go语言学习(十一)| 通道

通道类型的值本身就是并发安全的,这也是 Go 语言自带的、唯一一个可以满足并发安全性的类型。 通道声明及初始化 通道相当于一个先进先出的队列。在声明一个通道类型变量的时候,我们首先要确定该通道类型的元...
Go语言学习(十)| module 使用 编程语言

Go语言学习(十)| module 使用

requirement go module 是在go 1.11版本才开始有的,需要将环境变量 GO111MODULE 设置为 on 才能正常使用 例: export GO111MODULE=on 初次...
Go语言学习(四)| 数组、切片、集合 编程语言

Go语言学习(四)| 数组、切片、集合

array 声明数组 array由 <type> 定义,n为array的长度,标示希望存储的内容的类型。例: var arr int //声明一个int类型的数组 arr = 42 //数...
Go语言学习(二)| 变量 编程语言

Go语言学习(二)| 变量

Go变量的类型在变量名的后面。 声明单个变量 使用语法为: var var_name type , 例: var age int var age int = 10 //声明单个变量并初始化 声明多个变...
Go语言学习(一)| 环境搭建 编程语言

Go语言学习(一)| 环境搭建

Linux 下安装 已1.10.3 为例,下载源码包:下载地址 wget https://dl.google.com/go/go1.10.3.linux-amd64.tar.gz ​ 将下载的源码包解...