首页 文章

指针上定义的方法仍可使用值调用

提问于
浏览
3

“Effective Go”文档说明如下 .

关于接收器的指针与值的规则是可以在指针和值上调用值方法,但只能在指针上调用指针方法 .

http://tip.golang.org/doc/effective_go.html#pointers_vs_values

因此,如果我定义一个像下面这样的方法,它不会被一个值调用吗?

func (self *someStruct) Change(newNum int) {
    self.propertyOne = newNum
}

但是,以下似乎仍然有效 .

structInstance := &someStruct{
    propertyOne: 41,
}
(*structInstance).Change(456)

为什么?

它是否将值 (*structInstance) 转换回 Change 调用的地址/指针?

如何确保某个类型的实例无法调用指针上定义的方法(如 Change )?

去游乐场演示

http://play.golang.org/p/azbpp_djlG

2 回答

  • 2

    the language specification

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

    在您的示例中, (*structInstance) 的方法集中没有 Change 方法,但它是可寻址的,并且该方法存在于 &(*structInstance) 的方法集中,因此该调用被解释为 (&(*structInstance)).Change(456) ,或更简单地 structInstance.Change(456) .

    防止这种行为的唯一方法是在 someStruct 上定义 Change 方法,也许会让人感到恐慌 . 那实际上很重要 .

  • 1

    当在指针接收器上定义函数时,Go将自动将值转换为该函数的指针 .

    type Cookies struct {
        Num int
    }
    
    func (c *Cookies) Buy(n int) {
        c.Num += n
    }
    
    func main() {
        c := Cookies{}
        c.Buy(10) //is equal to (&c).Buy(10)
        fmt.Println(c)
    }
    

    我找不到现在定义的位置的引用,但我知道它在规范中的某个官方文档中 .

    另外请注意,请不要在Go中使用 selfthis .

    //编辑

    http://tip.golang.org/ref/spec#Calls

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

相关问题