01
概念
method 和函数类似,只是在函数名字前面多了一个参数,这个参数把这个 method 绑定到这个参数对应的类型上。
函数名字前面多的这个参数,我们称之为 method 的接收者,接收者名字最好能够选择简短且在整个 method 中名称始终保持一致的名字。通常的做法是取类型名字的首字母作为接收者名字。
因为 method 和成员变量的字段同属于一个命名空间,所以在 struct 类型中成员变量的字段名不能和 method 名字相同。否则会报编译错误。
因为每个类型有它自己的命名空间,所以我们可以在其它不同类型中使用相同的 method 名字。
在 Go 语言中,除了指针类型和接口类型之外,在同一个包下的其他任何类型都可以声明 method。
实参接收者会复制整个实参变量,如果实参变量太大,或者我们需要更新接收者变量,我们可以使用指针传递变量的地址。
method 的接收者允许 nil 指针作为实参,尤其是 map 和 slice 类型,其零值就是 nil 的类型。
02
实参接收者的 method
通过代码,我们演示实参接收者的 method。
type user struct { uid int uname string age uint16 } func (u *user) eat() string { str := fmt.Sprintf("I am %s, I am eating now.\n", u.uname) return str } func main() { u1 := &user{ uid: 2, uname: "lily", age: 19, } eater := u1.eat() fmt.Println(eater) fmt.Println(*u1) fmt.Println(u1) }
03
指针接收者的 method
通过代码,我们演示指针接收者的 method。
type user struct { uid int uname string age uint16 } func (u *user) eat() string { str := fmt.Sprintf("I am %s, I am eating now.\n", u.uname) return str } func main() { u1 := &user{ uid: 2, uname: "lily", age: 19, } eater := u1.eat() fmt.Println(eater) fmt.Println(*u1) fmt.Println(u1) }
提示:
在实际 Go 语言项目开发中,struct 类型的任何一个方法使用指针接收者,通常此类型的所有方法都应该使用指针接收者,不管方法需不需要使用指针接收者。
04
struct 内嵌匿名字段的 method
内嵌匿名字段可以方便地使用匿名字段的所有字段和方法,通过这种方式,可以组成复杂类型,每个匿名字段提供一些方法。
内嵌匿名字段可以是指向命名类型的指针,字段和方法间接地来自于指针指向的对象。
struct 类型可以拥有多个匿名字段,这个类型的值可以拥有所有字段的方法,和它自身声明的方法,在调用方法时,编译器选择方法的优先级从高往低依次是自身声明的方法、内嵌字段的方法、内嵌字段的内嵌字段的方法,在同一个层级有同名方法时,编译器会报错。
05
method 变量与 method表达式
method 变量是指将接收者的一个方法赋予一个变量,method 变量通常用于函数调用者期望函数的行为是调用一个特定接收者的 method。
method 表达式是指在调用 method 的时候,必须要提供接收者,把方法的接收者替换成函数的第一个形参,使它可以像函数一样调用。通常用于需要一个值代表属于同一个类型的多个 method 中的一个,method 变量可以帮助你调用这个值所对应的方法来处理不同的接收者。