Go语言中的方法
方法用于给指定数据类型(非内置数据类型)添加新的行为,方法实质上也是函数,与函数不同的是,每个方法包含了一个方法的作用对象参数,即:接收者。定义方法的语法为:
1 | package main |
为什么说方法实质上也是函数呢?因为它与下面的函数是等价的:
1 | func GetName(u user) string { |
方法的接收者
根据方法的语法,介于func
关键字和函数名之间的参数即为方法的接收者。
接收者的类型可以是值类型,也可以是指针类型:
1 | func (u user) GetName() string { |
接收者实质上也是作为一个参数传递给方法,Go语言中的参数传递方式都是值传递,所以:
- 在值类型接收者的方法中,在方法调用时会使用接收者值的一个副本来执行。
- 在指针类型的接收者方法中,在方法调用时会使用指针的一个副本来执行。
对于值类型的接收者方法来说,可以用指针来调用,反之亦然:
1 | var u1 = &user{1, "Alice"} |
如何选择接收者的类型
通常情况下,都将接收者设为指针类型。因为接收者为指针类型,所以对于状态的变更会直接影响到接收者,如果是值类型的接收器的话,则接收者不会受影响。
1 | func (u *user) SetId(id int) { |
从上面可以看出,如果需要对接收者做更改,需要使用指针类型的接收者。但不做更改的话是不是就可以使用值类型呢?如果是没有状态维护的结构体则可以使用值类型的接收者,如果结构体体积比较大,考虑到副本的拷贝效率,仍然建议使用指针类型的接收者。
1 | type matcher struct{} |
对于别名类型,也同样适用:
1 | type IntArray []int |
总结
Go语言中的方法可能会对其他语言的开发者来说有点不习惯,但方法的本质就是一个函数,接收者是该函数的第一个参数,从这个角度出发,该用指针接收者还是值接收者,就比较明确了。
欢迎指正!