最近在学习GoLang,因为一直从事java开发,对于在方法声明时是使用引用类型的参数还是指针类型的参数比较疑惑,在java中,我们只考虑值传递和引用传递,对于基本类型都是值传递形式,引用类型都是引用传递形式,但是Golang支持指针所以对于引用类型和指针类型比较难以选择,多方查阅现总结一下自己对他们的理解(针对java程序员,C/C++程序员勿喷).
Golang中没有class关键字来定义类,对于事物的抽象以struct来定义,因此一个struct变量我们可以看做一个类实例,但是这有别于java,因为他在方法传参时是值类型的而非引用类型,所以当我们需要在方法内改变这个对象的字段值时,我们应该使用的是struct变量的指针,而非struct变量.例如
type Student struct{ Name string } func (s * Student) Set(name string){ s.Name = name } func (s Student) Get()string{ return s.Name }
由上可知,
1、如果方法内部会修改当前对象的field或改变其值,需要用指针。
2、由于值传递是复制,因此,如果对象比较大,应该用指针,避免内存拷贝
注意:不见得使用指针就一定好过传值,因为按照 Go 的内存管理策略,涉及指针和引用的对象会被分配到 GC Heap 上。如果对象很 "小",显然要比在栈上进行值拷贝 "耗费" 更多。
另外与java不同的一点,数组Array在golang里并不被当做引用类型传递,而是值类型传递;按照Golang的说法,Golang中所有的类型都是属于值类型,但是有几个类型比较特殊,表现出引用类型的特征.分别是slice,map,channel,interface,除赋值以外他们都可以当做引用类型来使用.因此当我们这样做时,可以直接使用变量本身而不用指针:
type MyMap map[string]string func (s MyMap) Set(name,value string){ s[name] = value } func (s MyMap) Get(name string)string{ return s[name] }上面的例子由于MyMap是一个map,因此在方法中作为参数使用时可以直接使用MyMap来改变其值,而不用使用MyMap的指针,其实map本身是一个字典的指针.