Go语言中的方法和函数

在C#或者Java里面咱们都知道,一个Class是要包含成员变量和方法的,对于GO语言的Struct也同样,咱们也能够给Struct定义一系列方法。数组

1、怎么定义一个方法?函数

Go的方法是在函数前面加上一个接收者,这样编译器就知道这个方法属于哪一个类型了。例如:性能

package demo1 import ( "fmt" ) type Student struct { Name string Age int Class string } func (stu Student) GetUserInfo(student Student) { fmt.Printf("学生姓名:%v 年龄: %v 班级:%v ",student.Name,student.Age,student.Class) }

上面的代码就是定义了一个Student的结构体,而后针对这个结构体,建立了三个方法。咱们能够经过【实例名.方法名】的方式来访问这个结构体内的方法。测试

package main import "Function/demo1" func main(){ student:=demo1.Student{ Name:"XiaoMing", Age:20, Class:"3-2", } student.GetUserInfo(student) }

2、接收者的类型问题spa

上面的GetUserInfo的接收者是一个Student类型,这里就会出现一个问题,若是我是设定类的操做,那么不会改变对应实例的值,它只是一个拷贝。下面的例子将说明这个问题,下面这个Set方法接收者是Student指针

type Student struct { Name string Age int Class string } func (stu Student) SetStudentName(name string) { stu.Name = name }

main函数中使用这个类code

func main(){ student:=demo2.Student{ Name:"XiaoMing", Age:20, Class:"3-2", } student.SetStudentName("LiLie") fmt.Printf("Name: %v",student.Name ) }

结果:blog

Name: XiaoMing

能够看到,这里并没把Name进行修改。内存

若是咱们使用Student指针类型做为接收者,则会修改这个值。例子以下:编译器

func (stu *Student) SetStudentName(name string) { stu.Name = name //这里为何能stu直接.出Name,是Go的语法糖至关于 (*stu).Name
}

再次运营结果为:

Name: LiLie

3、什么时候使用值类型接收者,什么时候使用指针类型接收者。

粗暴的结论:若是你不知道怎么选择,那就使用指针。但有时候,使用值接收者会更合理,尤为是效率考虑,好比:不须要修改的小 struct、基础数据类型。如下是一些有用的指导方针:

- 若是接收者是 map、func 或 chan,不用使用指针。若是是 slice,而且方法不会 reslice 或 从分配 slice,不要使用指针;

- 若是方法须要修改接收者,必须使用指针; - 若是接收者是包含了 sync.Mutex 或相似的同步字段的结构体(struct),接收者必须使用指针,避免拷贝;

- 若是接收者是一个大的结构体或数组,使用指针会更高效。但多大是大?若是全部元素(struct 的字段或数组元素)做为方法的参数传递认为太大,那么做为接收者也是太大。(粗暴一些,全部元素内存超过指针大小,能够考虑使用指针);

- 若是接收者是结构体、数组或 slice,同时,它们的元素是指针,且指向的数据要改变,那么使用指针接收者会更合理;(有点绕,那就总原则:用指针没错);

- 若是接收者是小的数组,或小的没有可变字段或指针的结构体,或者结构体字段只是简单的基础类型,值接收者会更合理;值接收者能减小垃圾回收的压力,通常会优先分配在栈上(记住是通常,由于有可能逃逸);但除非有性能测试验证,不然别由于能够介绍垃圾回收压力,就选择值接收者;

最后再强调一下,若是你拿不定主意,那就用指针接收者。

相关文章
相关标签/搜索