首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >值方法和指针方法

值方法和指针方法

作者头像
数据小冰
发布2022-08-15 14:28:55
发布2022-08-15 14:28:55
1.5K00
代码可运行
举报
文章被收录于专栏:数据小冰数据小冰
运行总次数:0
代码可运行

1 函数与方法

函数与方法有什么区别?编程中的函数与数学中的函数定义是一致的,函数就是对给定的输入到输出的一个隐射变化,在面向过程的语言中,例如c语言,通常我们写的每个功能代码段称之为函数,在golang中也是一样。方法与函数的主要区别是,方法与对象绑定的,方法有属于它的一个对象,在go中,通常都是与一个struct关联在一起的。在下面的demo2中,say()是属于cat的方法,在调用的时候,需要(obejct cat).say()形式调用。

  • demo1 函数
代码语言:javascript
代码运行次数:0
运行
复制
func add(a, b int) int{
  return a+b
}
  • demo2 方法
代码语言:javascript
代码运行次数:0
运行
复制
type cat struct{}

func (d *dog) say() {
 fmt.Println("i am a dog")
}

func (c cat) say() {
 fmt.Println("i am a cat")
}

2 值方法和指针方法

golang中定义一个方法形式为 func (receiver) fname(){} ,函数(fname)+属于对象(recevier), 属于的对象一般称作接收者。接收者有两种形式,一种是值类型,一种是指针类型。下面的dog say为指针类型,cat say为值类型。

代码语言:javascript
代码运行次数:0
运行
复制
type dog struct{}

type cat struct{}

// say()方法的全名为(*dog).say()
// 即只有指针类型的*dog才有say()方法
// 值类型的dog是没有say()方法的
func (d *dog) say() {
 fmt.Println("i am a dog")
}

// say()方法的全名是(cat).say()
// 即只有值类型的cat才有say()方法
// 指针类型的*cat是没有say()方法的
func (c cat) say() {
 fmt.Println("i am a cat")
}

上面的say()方法是不一样的,虽然他们都叫say方法,因为他们的接受者类型是不一样的,对于dog,它的say全名为(dog).say(), 对于cat,它的say全名为(cat).say()。结合下面的代码,dp是dog类型,所以执行dp.say()肯定是没有问题的,cv是cat类型,执行cv.say()也是没有问题的。那dv.say()和cp.say()有没有问题呢?「没有问题」,编译能够正常通过并运行出正确的结果。

代码语言:javascript
代码运行次数:0
运行
复制
func main() {
 dv := dog{}
 dp := &dog{}

 cv := cat{}
 cp := &cat{}

 dv.say()
 dp.say()

 cv.say()
 cp.say()
}

为什么会这样呢?是编译器帮我们做了隐式转换。即将dv.say()自动帮我转换成了(&dv).say(),也就是对dv进行了取地址操作。同理对cp.say()自动转为(*cp).say()。那定义了func (d *dog) say()还能定义func (d dog) say()吗,「不可用」,编译器会直接报错。也不能定义func (c cat) say()再定义func (c *cat) say()

3 接口类型编译器不会自动转换

我们定义一个接口类型sayer,里面有个say方法。

代码语言:javascript
代码运行次数:0
运行
复制
type sayer interface {
 say()
}

按照前面的理解,*dog和dog都可以调用say()方法,所以他们都实现了sayer。「不是这样」,对于接口类型,编译器并不会自动为我们做转换,所以要严格区分开,dog say的全名为(*dog).say()。所以只有指针类型的dog实现了sayer方法。将dog类型的dv赋值给say直接编译不通过。

代码语言:javascript
代码运行次数:0
运行
复制
var say sayer
say = dp

say = dv  //编译器直接报错

那要怎么赋值呢?

代码语言:javascript
代码运行次数:0
运行
复制
var say sayer
say = &dv  //这样赋值

看完这篇文章,再也不用担心我搞不清楚指针类型和值类型接收者的区别了!^^^

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-05-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 数据小冰 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1 函数与方法
  • 2 值方法和指针方法
  • 3 接口类型编译器不会自动转换
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档