C++是一种面向对象的编程语言,我们可以为类提供成员变量和成员方法。而在Go中没有类的概念,但是也提供了类似的机制来表示,那就是方法。
Go语言中的方法(method)是一种作用于特定类型变量的函数。这种特定类型变量叫做接收器(receiver)。如果将特定类型理解为结构体或类,那接收器的概念就类似于其他语言中的this或者self.
在Go语言中,接收器的类型可以是任何类型,不仅仅是结构体,任何类型都可以拥有方法,但必须是通过type定义的类型。
1.接收器--方法作用的目标
(1)接收器的格式
func (接收器变量 接收器类型) 方法名(参数列表) (返回参数){
//函数体
}
举例说明:
package main
import "fmt"
type Bag struct {
items []int
}
//面向过程
func Insert(b *Bag, itemid int) {
b.items = append(b.items, itemid)
}
//类似面向对象
func (b *Bag)Insert_method(itemid int) {
b.items = append(b.items, itemid)
}
func main() {
b := new(Bag)
Insert(b, 12)
Insert(b, 13)
Insert(b, 14)
Insert(b, 15)
fmt.Printf("%+v\n", b)
b.Insert_method(1111)
b.Insert_method(1113)
b.Insert_method(1115)
b.Insert_method(1117)
fmt.Printf("%+v\n", b)
}
2.接收器类型
接收器的类型分为指针接收器和非指针接收器。两种接收器在使用时会产生不同的效果。根据效果的不同,两种接收器会被用于不同性能和功能要求的代码中。
(1)指针类型接收器
指针类型的接收器由一个结构体的指针组成,更接近于面向对象中的this或者self.
由于指针的特性,调用方法时,修改接收器指针的任意成员变量,在方法结束后,修改都是有效的。、
(2)非指针类型的接收器
当方法作用于非指针接收器时,Go语言会在代码运行时将接收器的值复制一份。在非指针接收器的方法中可以获取接收器的成员值,但修改后无效。
(3)指针和非指针类型接收器的使用
在计算机中,小对象由于值复制时的速度比较快,所以适合使用非指针接收器。大对象因为复制性能低,适合使用指针接收器,在接收器和参数间传递时不进行复制,只传递指针。
3.方法和函数的统一调用
无论是普通函数还是结构体的方法,只要它们的签名一致,与它们签名一致的函数变量就可以保存普通函数或结构体方法。
package main
import "fmt"
type class struct {
}
func (c *class) Do(v int) {
fmt.Println("call method do:", v)
}
func funcDo(v int) {
fmt.Println("call function do:", v)
}
func main() {
var delegate func(int) //声明一个函数变量,带有一个整型参数,没有返回值
c := new(class)
delegate = c.Do
delegate(100)
delegate = funcDo
delegate(100)
}