-
博文分类专栏
- Jquery基础教程
-
- 文章:(15)篇
- 阅读:46569
- shell命令
-
- 文章:(42)篇
- 阅读:154247
- Git教程
-
- 文章:(36)篇
- 阅读:234885
- leetCode刷题
-
- 文章:(76)篇
- 阅读:131875
-
go语言中方法的接受者是指针和对象的区别是什么2018-12-23 11:26 阅读(5744) 评论(0)
一、概述
go语言中,方法的接受者可以是指针,也可以是对象。那么指针和对象的区别是什么?如下:
type Student struct { name string age int8 } func (this Student) setName1(name string) { this.name = name } func (this * Student) setName2(name string) { this.name = name }
测试案例1如下:
t1 := Student{name:"张三", age:18} fmt.Println("调用setName1前,t1的name", t1.name) t1.setName1("张三1") fmt.Println("调用setName1后,t1的name", t1.name) fmt.Println("调用setName2前,t1的name", t1.name) t1.setName2("张三2") fmt.Println("调用setName1后,t1的name", t1.name)
执行结果如下:
调用setName1前,t1的name 张三
调用setName1后,t1的name 张三
调用setName2前,t1的name 张三
调用setName1后,t1的name 张三2
故,可以得知如果接受者是指针,可以修改接受者。
测试案例2如下:
t2 := &Student{name:"t2_张三", age:18} fmt.Println("调用setName1前,t2的name", t2.name) t2.setName1("t2张三1") fmt.Println("调用setName1后,t2的name", t2.name) fmt.Println("调用setName2前,t1的name", t2.name) t2.setName2("t2张三2") fmt.Println("调用setName1后,t1的name", t2.name)
执行结果如下:
调用setName1前,t2的name t2_张三 调用setName1后,t2的name t2_张三 调用setName2前,t1的name t2_张三 调用setName1后,t1的name t2张三2
Student 类型 ,可以调用接受类型为 Student 和 *Student 类型的方法
* Student 类型,也可以调用接受类型为 Student 和 *Student 类型的方法。
区别在于,接受类型为 *Student 的方法,可以修改当前实参的内容。
我们可以使用形参和实参来总结一下,func (this Student)形参为对象,func (this * Student)形参为指针。如下:
形参(接受者) 对象 指针 实参 对象 指针 对象 指针 结果 可调用 可调用,可以修改对象。
可调用 可调用,可以修改对象 二、开发中方法的接受者使用指针类型还是使用对象类型呢
1、如时使用指针类型
1.如果方法需要修改接受者,接受者必须是指针类型。
2.如果接受者是一个包含了 sync.Mutex 或者类似同步字段的结构体,接受者必须是指针,这样可以避免拷贝。
3.如果接受者是一个大的结构体或者数组,那么指针类型接受者更有效率。
4.如果接受者是一个结构体,数组或者 slice,它们中任意一个元素是指针类型而且可能被修改,建议使用指针类型接受者,这样会增加程序的可读性
2、如时使用值类型(对象类型)
1.如果接受者是一个 map,func 或者 chan,使用值类型(因为它们本身就是引用类型)。
2.如果接受者是一个 slice,且方法内的变动,对参数没有影响
3.如果接受者是一个小的数组或者原生的值类型结构体类型(比如 time.Time 类型),而且没有可修改的字段和指针,又或者接受者是一个简单地基本类型像是 int 和 string,使用值类型就好了。