美文网首页
Go语言如何选择方法接收器的类型

Go语言如何选择方法接收器的类型

作者: pyihe | 来源:发表于2020-08-12 11:24 被阅读0次

Go语言中的方法

方法用于给指定数据类型(非内置数据类型)添加新的行为,方法实质上也是函数,与函数不同的是,每个方法包含了一个方法的作用对象参数,即:接收者。定义方法的语法为:

package main

import "fmt"

type user struct{
    id   int
    name string 
}

//方法的定义: 接收者位于func关键字和方法名之间
func (u user) GetName() string {
    return u.name
}

func main() {
    u := user{0, "John"}
    u.GetName() //方法的调用
}

为什么说方法实质上也是函数呢?因为它与下面的函数是等价的:

func GetName(u user) string {
    return u.name
}

方法的接收者

根据方法的语法,介于func关键字和函数名之间的参数即为方法的接收者。

接收者的类型可以是值类型,也可以是指针类型:

func (u user) GetName() string {
    return u.name
}

func (u *user) GetId() int {
    return u.id
}

接收者实质上也是作为一个参数传递给方法,Go语言中的参数传递方式都是值传递,所以:

  1. 在值类型接收者的方法中,在方法调用时会使用接收者值的一个副本来执行。
  2. 在指针类型的接收者方法中,在方法调用时会使用指针的一个副本来执行。

对于值类型的接收者方法来说,可以用指针来调用,反之亦然:

var u1 = &user{1, "Alice"}
u1.GetName() //执行时相当于: (*u1).GetName()

var u2 = user{2, "John"}
u2.GetId() //执行时相当于: (&u2).GetId()

如何选择接收者的类型

通常情况下,都将接收者设为指针类型。因为接收者为指针类型,所以对于状态的变更会直接影响到接收者,如果是值类型的接收器的话,则接收者不会受影响。

func (u *user) SetId(id int) {
    u.id = id
}

func (u user) SetName(name string) {
    u.name = name
}

var u user
u.SetId(1) //变量u的id会被更改
u.SetName("Tracy") //变量u的name不会被更改

从上面可以看出,如果需要对接收者做更改,需要使用指针类型的接收者。但不做更改的话是不是就可以使用值类型呢?如果是没有状态维护的结构体则可以使用值类型的接收者,如果结构体体积比较大,考虑到副本的拷贝效率,仍然建议使用指针类型的接收者。

type matcher struct{}

func (m matcher) Match(args ...interface)  {
 //因为没有状态维护,所以可以使用值接收者
}

对于别名类型,也同样适用:

type IntArray []int

func (ia IntArray) Len() int {
    return len(ia)
}

func (ia *IntArray) Del(target int)  {
    for i, v := range *ia {
        if v == target {
            (*ia) = append((*ia)[:i], (*ia)[i+1:]...)
            break
        }   
    }
}

总结

Go语言中的方法可能会对其他语言的开发者来说有点不习惯,但方法的本质就是一个函数,接收者是该函数的第一个参数,从这个角度出发,该用指针接收者还是值接收者,就比较明确了。

欢迎指正!

原文链接:Go语言如何选择方法接收器的类型

相关文章

  • Go Method

    Go语言同时支持函数和方法,方法是包含接收器的函数,接收器可以是命名类型或结构体类型的值或指针。为特定类型定义的方...

  • Go语言如何选择方法接收器的类型

    Go语言中的方法 方法用于给指定数据类型(非内置数据类型)添加新的行为,方法实质上也是函数,与函数不同的是,每个方...

  • Go接口实例

    Go支持在struct类型上定义的方法。area方法有一个* rect类型的接收器。可以为指针或值接收器类型定义方...

  • Go接口实例

    Go支持在struct类型上定义的方法。area方法有一个* rect类型的接收器。可以为指针或值接收器类型定义方...

  • 02-Go语言常量和变量

    Go语言的数据类型 C语言的数据类型 Go语言的数据类型 Go语言各数据类型占用内存空间 Go语言中也可以使用si...

  • Learning Go(1)

    Go是面向接口和函数式编程的语言; Go只有值类型和指针类型 在写可调用方法时,方法名要大写; “=”和“:...

  • 04GoLang类型转换

    数值类型之间的转换 在C语言中如何转换 1.1隐式转换 1.2显示转换 Go语言中如何转换 在Go语言中只有显示转...

  • 数据类型转换

    数值类型之间的转换 在C语言中如何转换1.隐式转换 2.显示转换 Go语言中如何转换 在Go语言中只有显示转换, ...

  • Go变量声明

    go变量类型声明 变量短声明go语言是强类型语言所以在变量的声明中制定类型,但是在方法中声明的变量可以不需要关键字...

  • Go 语言程序设计——集合类型(1)

    Go语言的所有内置类型:数组、切片和映射 值、指针和引用类型 值在传递给函数或者方法的时候会被复制一次 Go语言中...

网友评论

      本文标题:Go语言如何选择方法接收器的类型

      本文链接:https://www.haomeiwen.com/subject/nfupdktx.html