方法

  • 只能未当前包含命令类型定义方法
  • 参数receiver可任意命名。如方法中未曾使用,可省略参数名
  • 参数receiver类型可以是T或者是*T。基类型T不能是接口或指针
  • 不支持方法重载,receiver知识参数签名的组成部分
  • 可用实例value或pointer调用全部方法,编译器自动转换

一个方法就是一个包含了接收者的函数,接收者可以是命名类型或者结构体类型的一个值或者是一个指针

所有给定类型的方法属于该类型的方法集

```go //当接收者不是一个指针的时候,该方法操作对应接收者的值的副本(意思就是即使使用了指针调用函数,但是函数的接收者是值类型)所以函数内部操作还是对副本的操作,而不是指针操作 package main

import “fmt”

type User struct { Name string Email string }

func (u User) Notify() { fmt.Printf(“%v: %v \n”, u.Name, u.Email) } func main() { //值类型方法调用 user := User{Name: “Golang”, Email: “Goland.com”} user.Notify()

  1. //指针类型调用方法
  2. u := &User{Name: "Golang", Email: "Goland"}
  3. u.Notify()

}

//当接收者是一个指针的时候,即使用值类型调用那么函数内部也是对指针的操作。

func (u *User) Notify() { fmt.Printf(“%v: %v \n”, u.Name, u.Email) } func main() { //值类型方法调用 user := User{Name: “Golang”, Email: “Goland.com”} user.Notify()

  1. //指针类型调用方法
  2. u := &User{Name: "Golang", Email: "Goland"}
  3. u.Notify()

}

  1. <a name="9d31d591"></a>
  2. #### receiver T 和 `*T` 的差别
  3. > ```go
  4. package main
  5. import "fmt"
  6. type User struct {
  7. Name string
  8. Email string
  9. }
  10. func (u User) Notify_1() {
  11. fmt.Printf("Value: %p\n", &u)
  12. }
  13. func (u *User) Notify_2() {
  14. fmt.Printf("Pointer: %p\n", u)
  15. }
  16. func main() {
  17. user := User{Name: "张三", Email: "Goland.com"}
  18. //0xc0000503c0
  19. var u = &user
  20. fmt.Printf("u: %p\n", u)
  21. //0xc000050400 传入的receiver 接收者实参 发生了值拷贝
  22. user.Notify_1()
  23. //0xc0000503c0 传入的receiver 接收者实参 还是使用的指针值
  24. user.Notify_2()
  25. //0xc000050420 传入的receiver 接收者实参 发生了值拷贝
  26. u.Notify_1()
  27. // 传入的receiver 接收者实参 还是使用的指针值
  28. u.Notify_2()
  29. }

普通函数与方法的区别

  1. 对于普通函数接收者是值类型时,不能直接将指针类型的数据直接传递 反过来也一样
  2. 对于方法如struct方法,接收者为值类型时,可以直接用指针类型的变量调用方法,反过来同样可以