pointers - 非指针类型的指针方法

标签 pointers go methods

根据对此 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()

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

(&c).fourWheels()

这是在Spec: Calls:

If x is addressable and &x's method set contains m, 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/

相关文章:

go - 如何处理 NewCB​​CDecrypter 示例中的无效 key ?

java - 不使用数组编写此方法的另一种方法

javascript - 使用c#将用户数据设置为HTML标签

c - 理解指向指针概念的指针

objective-c - 在 Swift 中使用对 CFPropertyListRef 的引用

c - 这个指针是否安全声明?

go - 无法识别ubuntu 18.04上安装的Goose

google-app-engine - GAE Go 在注销时执行其他操作

c - 将条目附加到链表的末尾

java - java中的类方法和构造函数混淆