1. 铺垫:Go 的接收器Receiver
在go语言中,没有类的概念,但是可以给类型(结构体,自定义类型)定义方法。所谓方法就是定义了接受者的函数。接受者定义在func关键字和函数名之间。可以理解成为结构体定义函数方法,类似于C++中的类方法。
type Person struct {
name string
age int
}
func (p Person) say() {
fmt.Printf("I'm %s,%d years old\n",p.name,p.age)
}
接受者类型可以是struct,也可以是指向struc的指针。
- 接收者的类型为struct
package main
import "fmt"
type Person struct {
name string
age int
}
func (p Person) say() {
fmt.Printf("I'm %s,%d years old\n",p.name,p.age)
}
func (p Person) older(){
p.age = p.age +1
}
func main() {
var p1 Person = Person{"lineshen",25}
p1.older()
p1.say()
var p2 *Person = &Person{"leleyue",22}
p2.older()
p2.say()
}
output:
I'm lineshen,25 years old
I'm leleyue,22 years old
对于p1的调用,是没有问题的,因为传递的是结构体,在方法中改变结构体属性,并不能改变原来内存中的值。
对于p2的调用会产生疑问,p2明明是个指针,为什么再调用了older方法之后,打印结果还是22 years old?
方法的接受者是Person而调用者是*Person。其实在p2调用时存在一个转换p2.older() -> *p2.older(); p2.say() -> *p2.say()
p2是指向Person实例的指针。因此,方法执行时的接受者实际上还是一个值而非引用,因此值是不会发生改变的。
- 接收者的类型为指针
package main
import "fmt"
type Person struct {
name string
age int
}
func (p *Person) say() {
fmt.Printf("I'm %s,%d years old\n",p.name,p.age)
}
func (p *Person) older(){
p.age = p.age +1
}
func main() {
var p1 Person = Person{"lineshen",25}
p1.older()
p1.say()
var p2 *Person = &Person{"leleyue",22}
p2.older()
p2.say()
}