一尘不染

非指针类型的指针方法

go

根据这个问题的回答

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

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

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

那么,这是怎么了?这是新功能吗?还是对问题的回答是错误的?


阅读 303

收藏
2020-07-02

共1个答案

一尘不染

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

c.fourWheels()

c是类型car(非指针);由于该car.fourWheels()方法具有指针接收者,并且由于接收者值是非指针且可寻址,因此它是以下各项的简写形式:

(&c).fourWheels()

这是在规范中:致电:

如果x可寻址&x方法集包含mx.m()则为的简写(&x).m()

该声明:

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

像这样解释它:

  • 如果您有一个值方法,则可以 随时 调用它:如果您有值,则它随时可以成为接收方;如果您有一个指针,则可以随时对其取消引用以获得一个随时可以用作接收器的值。

  • 如果您有一个指针方法,则只有一个值时 可能无法始终 调用它,因为存在多个无法寻址的表达式(其结果),因此您将无法获得指向该方法的指针。将用作接收器;这样的示例是函数返回值和映射索引表达式。

2020-07-02