method

2022-01-04  本文已影响0人  JunChow520

Go中方法是作用在指定的数据类型上的,即必须和指定的数据类型绑定,因此自定义类型都可以具有方法,而不仅仅是结构体。

方法声明与调用

方法的定义

func (receiver type) methodName (argument_list) (return_value_list) {
  // method body
  return value
}
元素 描述
argument_list 参数列表,表示方法的输入。
receiver type 表示方法和指定的type类型进行绑定,该方法作用于type类型。type可以是结构体也可以是自定义类型。
receiver type类似的一个实例变量
return_value_list 返回值列表,表示返回的值,可以为多个。
method_body 方法体,为实现某功能的代码块。
return return语句不是必须的
type User struct {
    Id int
}
// 为User类型绑定TableName方法
func (t User) TableName() string {
    fmt.Printf("%+v\n", t)
    return "users"
}

func main() {
    u := User{1}
    name := u.TableName()
    fmt.Println(name)
}

语法说明

方法的调用和传参机制

方法的调用和传参机制和函数基本一致,不同之处在于方法调用时会将调用方法的变量作为实参也传递给方法,若变量是值类型则进行值拷贝,若变量是引用类型,则进行地址拷贝。

type Circle struct {
    radius float64
}

func (t Circle) area() float64 {
    return 3.14 * t.radius * t.radius
}

func main() {
    var c Circle
    c.radius = 4.0
    res := c.area()
    fmt.Println(res) // 50.24
}

由于采用值拷贝的方式效率较低,建议采用传递指针的方式以提升效率。

注意事项

type User struct {
    Id   int
    Name string
}

func (t *User) String() string {
    str := fmt.Sprintf("id:%d, name:%s\n", t.Id, t.Name)
    return str
}

func main() {
    u := User{1, "alice"}
    fmt.Println(&u)
}

方法与函数

方法和函数的区别

区别 函数 方法
调用方式 函数名(实参列表) 变量.方法名(实参列表)
接收值类型时 不能将指针类型的数据直接传递 可直接使用指针类型的变量调用方法
type User struct {
    Id   int
    Name string
}

func (t *User) Print() {
    fmt.Printf("id:%d, name:%s\n", t.Id, t.Name)
}

func main() {
    u := User{1, "alice"}
    u.Print()
    (&u).Print()
}

注意:从形式上看(&u)是传入地址,但本质仍然是值拷贝。

type User struct {
    Id   int
    Name string
}

func (t User) Print() {
    t.Id = 2
    fmt.Printf("id:%d, name:%s\n", t.Id, t.Name)
}

func main() {
    u := User{1, "alice"}
    u.Print()                                    // id:2, name:alice
    (&u).Print()                                 // id:2, name:alice
    fmt.Printf("id:%d, name:%s\n", u.Id, u.Name) // id:1, name:alice
}
上一篇 下一篇

猜你喜欢

热点阅读