【问题标题】:Pointer methods on non pointer types非指针类型的指针方法
【发布时间】:2023-04-07 18:54:01
【问题描述】:

据此回复此question

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

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

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)
}

那么,这里有什么问题?这是一个新功能吗?还是对问题的回答有误?

【问题讨论】:

    标签: pointers go methods


    【解决方案1】:

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

    c.fourWheels()
    

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

    (&c).fourWheels()
    

    这是Spec: Calls:

    如果xaddressable 并且&x 的方法集包含m,则x.m()(&x).m() 的简写。

    声明:

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

    这样解释:

    • 如果你有一个值方法,你可以总是调用它:如果你有一个值,它就可以成为接收者;如果你有一个指针,你总是可以取消引用它以获得一个准备好成为接收者的值。

    • 如果你有一个指针方法,如果你只有一个值,你可能并不总是能够调用它,因为有几个表达式(其结果)是不可寻址的,并且因此,您将无法获得将用作接收器的指向它的指针;这样的例子是函数返回值和映射索引表达式。详情及示例见How can I store reference to the result of an operation in Go?;和How to get the pointer of return value from function call?(当然,你总是可以将它分配给一个局部变量并获取它的地址,但这是一个 copy 并且指针方法只能修改这个副本而不是原始的。)

    【讨论】:

    • 说得好 - 最后一个项目符号是关键,并解释了一些可能会让新地鼠感到困惑的情况。
    猜你喜欢
    • 2015-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-03
    • 2023-03-08
    • 1970-01-01
    • 2018-07-05
    • 1970-01-01
    相关资源
    最近更新 更多