为了账号安全,请及时绑定邮箱和手机立即绑定

使用指针接收器调用函数的语法

使用指针接收器调用函数的语法

Go
LEATH 2021-05-03 13:53:24
在Go中,如果我定义了一个以指针作为接收器的函数,那么它不应该只允许从指针调用该函数吗?为什么可以从值本身调用此函数并产生相同的效果。例如,在以下程序中:m1.reset()和m2.reset()具有相同的效果。即使m1是一个值,而m2是一个指针。我有点困惑,因为有两种方法可以做同一件事,而且不确定要遵循哪种方法。尽管大多数代码遵循使用指针字段调用函数的约定。我想念什么吗?package main    import "fmt"    type MyStruct struct {        X int    }    func (m *MyStruct) reset() {        m.X = 0    }    func main() {        m1 := MyStruct{1}        m2 := &MyStruct{1}        fmt.Println(m1.X)        fmt.Println(m2.X)        m1.reset()        m2.reset()        fmt.Println(m1.X)        fmt.Println(m2.X)    }
查看完整描述

3 回答

?
慕姐4208626

TA贡献1852条经验 获得超7个赞

规格

对应的指针类型* T的方法集是接收者* T或T的所有方法的集(也就是说,它也包含T的方法集)。

关于方法调用的下一条必要信息如下:

x.m()如果x的方法集(类型)包含m并且参数列表可以分配给m的参数列表,则该方法调用有效。如果x是可寻址的并且&x的方法集包含m,x.m()则是x的简写(&x).m()

将以上两个内容放在一起,您将获得所看到的行为。


查看完整回答
反对 回复 2021-05-10
?
一只萌萌小番薯

TA贡献1795条经验 获得超7个赞

提供了完美的文档规范说明,但我想基于您的示例添加一个代码示例。我认为您的重点应该放在“为什么有两种方法来做同一件事”上,而不是在何时使用一种方法与另一种方法上。具有指针作为接收者的方法具有修改该接收者的值的能力,而具有具有接收者的值的方法则不能修改。这是因为这些方法接收接收者的副本。当您获得一个指针的副本时,您仍然可以修改其值。当您收到该值的副本时,您在该方法中所做的更改只会更改副本,而不会更改原始副本:


package main


import "fmt"


type MyStruct struct {

    X int

}


func (m *MyStruct) resetPtr() {

    m.X = 0

}


func (m MyStruct) resetValue() {

    m.X = 0

}


func main() {

    m1 := MyStruct{1}

    m2 := &MyStruct{1}


    fmt.Println("Original Values:", m1.X, m2.X)


    m1.resetPtr()

    m2.resetPtr()


    fmt.Println("After resetPtr():", m1.X, m2.X)


    m1 = MyStruct{1}

    m2 = &MyStruct{1}


    m1.resetValue()

    m2.resetValue()


    fmt.Println("After resetValue():", m1.X, m2.X)

}

输出


Original Values: 1 1

After resetPtr(): 0 0

After resetValue(): 1 1

您可以看到访问这些变量的方式并不是真正的问题。它的更多内容是您可以在方法内部使用它们做什么,以及如何将它们作为参数传递给其他函数或方法(正在复制)。


查看完整回答
反对 回复 2021-05-10
?
婷婷同学_

TA贡献1844条经验 获得超8个赞

简短的解释是,幕后的Go编译器会自动转换:

m1.reset()
m2.reset()

进入:

(&m1).reset()
m2.reset()


查看完整回答
反对 回复 2021-05-10
  • 3 回答
  • 0 关注
  • 226 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信