根据对此 question 的回复
The rule about pointers vs. values for receivers is that value methods can be invoked on pointers and values, but pointer methods can only be invoked on pointers
但实际上我可以对非指针值执行指针方法:
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()
这是在Spec: Calls:
If
x
is addressable and&x
's method set containsm
,x.m()
is shorthand for(&x).m()
.
声明:
The rule about pointers vs. values for receivers is that value methods can be invoked on pointers and values, but pointer methods can only be invoked on pointers
这样解释:
如果你有一个值方法,你可以总是调用它:如果你有一个值,它就准备好成为接收者;如果你有一个指针,你总是可以取消引用它以获得一个准备好成为接收者的值。
如果您有一个指针方法,如果您只有一个值,您可能并不总是能够调用它,因为有几个表达式(其结果)是不可寻址的,并且因此,您将无法获得指向它的指针以用作接收器;这样的例子是函数返回值和映射索引表达式。有关详细信息和示例,请参阅 How can I store reference to the result of an operation in Go? ;和 How to get the pointer of return value from function call? (当然,您总是可以将它分配给一个局部变量并获取它的地址,但那是一个副本,指针方法只能修改这个副本而不是原始的。)
关于pointers - 非指针类型的指针方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46956290/