method

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

方法声明与调用

方法的定义

func (receiver type) methodName (argument_list) (return_value_list) {
  // method body
  return value
}
元素描述
argument_list参数列表,表示方法的输入。
receiver type表示方法和指定的type类型进行绑定,该方法作用于type类型。type可以是结构体也可以是自定义类型。
receivertype类似的一个实例变量
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)
}

语法说明

  • func (t User) TableName(){}表示User类型具有一个方法,方法名称为TableName
  • (t User)体现了TableName方法是和User类型绑定的
  • TableName()方法只能通过User类型的变量来调用,而不能直接调用,也不能使用其它类型变量来调用。
  • (t User)中的t变量表示哪个User变量调用,这个t就是它的副本,类似函数传参。
  • 若需要传入引用类型而不采用副本的方式可使用(t *User)的方式
  • t这个名字由开发人员自行指定,不是固定的。

方法的调用和传参机制

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

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
}

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

注意事项

  • 结构体类型是值类型,方法调用中遵守值类型的传递机制,即值类型采用的是值拷贝传递的方式。
  • 若希望在方法中修改结构体变量的值可通过结构体指针的方式来处理
  • Go中方法的作用是在指定的数据类型上(和指定的数据类型绑定),因此自定义类型都可以有方法,而不仅仅是结构体,基本类型也可以拥有方法。
  • 方法的访问范围控制的规则和函数一样,方法名首字母小写只能在本包访问,首字母大写可以在本包和其它包访问。
  • 若某个变量实现了String()方法则fmt.Println()默认会调用此变量的String()方法进行输出。
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
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值