Go 方法

一般的函数定义叫做函数,定义在结构体上面的函数叫做该结构体的方法。

示例1:

  1. package main
  2. import "fmt"
  3. type rect struct {
  4. width, height int
  5. }
  6. // 这个area方法有一个限定类型*rect,
  7. // 表示这个函数是定义在rect结构体上的方法
  8. func (r *rect) area() int {
  9. return r.width * r.height
  10. }
  11. // 方法的定义限定类型可以为结构体类型
  12. // 也可以是结构体指针类型
  13. // 区别在于如果限定类型是结构体指针类型
  14. // 那么在该方法内部可以修改结构体成员信息
  15. func (r rect) perim() int {
  16. return 2*r.width + 2*r.height
  17. }
  18. func main() {
  19. r := rect{width: 10, height: 5}
  20. // 调用方法
  21. fmt.Println("area: ", r.area())
  22. fmt.Println("perim:", r.perim())
  23. // Go语言会自动识别方法调用的参数是结构体变量还是
  24. // 结构体指针,如果你要修改结构体内部成员值,那么使用
  25. // 结构体指针作为函数限定类型,也就是说参数若是结构体
  26. //变量,仅仅会发生值拷贝。
  27. rp := &r
  28. fmt.Println("area: ", rp.area())
  29. fmt.Println("perim:", rp.perim())
  30. }

输出结果为

  1. area: 50
  2. perim: 30
  3. area: 50
  4. perim: 30

示例2:

从某种意义上说,方法是函数的“语法糖”。当函数与某个特定的类型绑定,那么它就是一个方法。也证因为如此,我们可以将方法“还原”成函数。

instance.method(args)->(type).func(instance,args)

为了区别这两种方式,官方文档中将左边的称为Method Value,右边则是Method Expression。Method Value是包装后的状态对象,总是与特定的对象实例关联在一起(类似闭包,拐带私奔),而Method Expression函数将Receiver作为第一个显式参数,调用时需额外传递。

注意:对于Method Expression,T仅拥有T Receiver方法,T拥有(T+T)所有方法。

  1. package main
  2. import (
  3. "fmt"
  4. )
  5. func main() {
  6. p := Person{2, "张三"}
  7. p.test(1)
  8. var f1 func(int) = p.test
  9. f1(2)
  10. Person.test(p, 3)
  11. var f2 func(Person, int) = Person.test
  12. f2(p, 4)
  13. }
  14. type Person struct {
  15. Id int
  16. Name string
  17. }
  18. func (this Person) test(x int) {
  19. fmt.Println("Id:", this.Id, "Name", this.Name)
  20. fmt.Println("x=", x)
  21. }

输出结果:

  1. Id: 2 Name 张三
  2. x= 1
  3. Id: 2 Name 张三
  4. x= 2
  5. Id: 2 Name 张三
  6. x= 3
  7. Id: 2 Name 张三
  8. x= 4

示例3:

使用匿名字段,实现模拟继承。即可直接访问匿名字段(匿名类型或匿名指针类型)的方法这种行为类似“继承”。访问匿名字段方法时,有隐藏规则,这样我们可以实现override效果。

  1. package main
  2. import (
  3. "fmt"
  4. )
  5. func main() {
  6. p := Student{Person{2, "张三"}, 25}
  7. p.test()
  8. }
  9. type Person struct {
  10. Id int
  11. Name string
  12. }
  13. type Student struct {
  14. Person
  15. Score int
  16. }
  17. func (this Person) test() {
  18. fmt.Println("person test")
  19. }
  20. func (this Student) test() {
  21. fmt.Println("student test")
  22. }

输出结果为:

  1. student test