Pointers 非指针类型上的指针方法

Pointers 非指针类型上的指针方法,pointers,go,methods,Pointers,Go,Methods,根据这一回应, 关于指针与接收器值的规则是,可以对指针和值调用值方法,但只能对指针调用指针方法 但事实上,我可以对非指针值执行指针方法: package main import "fmt" type car struct { wheels int } func (c *car) fourWheels() { c.wheels = 4 } func main() { var c = car{} fmt.Println("Wheels:", c.wheels

根据这一回应,

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

但事实上,我可以对非指针值执行指针方法:

package main

import "fmt"

type car struct {
    wheels int
}

func (c *car) fourWheels() {
    c.wheels = 4
}

func main() {

    var c = car{}
    fmt.Println("Wheels:", c.wheels)
    c.fourWheels()
    // Here i can execute pointer method on non pointer value
    fmt.Println("Wheels:", c.wheels)
}
那么,这里出了什么问题?这是新功能吗?或者对问题的回答是错误的?

您正在对指针值调用“指针方法”。在表达式中:

c.fourWheels()
c
类型为
car
(非指针);由于
car.fourWheels()
方法具有指针接收器,并且接收器值是非指针且可寻址的,因此它是以下内容的简写:

(&c).fourWheels()
这是在

如果
x
是且
&x
的方法集包含
m
x.m()
(&x.m()
的缩写

声明:

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

这样理解:

  • 如果你有一个value方法,你可以随时调用它:如果你有一个value,它就可以成为接收者;如果你有一个指针,你总是可以去引用它来获得一个值,这个值可以作为接收者

  • 如果你有一个指针方法,如果你只有一个值,你可能不总是能够调用它,因为有几个表达式(其结果)是不可寻址的,因此你将无法获得一个指向它的指针,它将被用作接收器;例如函数返回值和映射索引表达式。有关详细信息和示例,请参见;和(当然,您可以始终将其分配给局部变量并获取其地址,但这是一个副本,指针方法只能修改此副本而不能修改原始副本。)


说得很好-最后一个要点是钥匙,它解释了一些可能会让新地鼠感到困惑的情况。