非指针类型的指针方法 [英] Pointer methods on non pointer types

查看:202
本文介绍了非指针类型的指针方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据对此问题的回应,


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

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

<$ p $ package main

importfmt

type car struct {
wheels int
}

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

func main(){

var c = car {}
fmt.Println(Wheels:,c.wheels)
c.fourWheels()
//这里我可以对非指针值
执行指针方法fmt.Println(Wheels:,c.wheels)
}

这里错了吗?这是一项新功能吗?或者对这个问题的回答是错误的?

解决方案

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

  c.fourWheels()

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

 (& c).fourWheels()

这是规范:电话:


如果 x addressable and & x 的方法集包含 m xm()简写为(& x).m()


声明:


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


解释如下: p>


  • 如果你有一个值方法,y你可以随时调用它:如果你有一个值,它已经准备好成为接收者;如果你有一个指针,你可以通过取消引用它来获得一个准备好成为接收者的值。

  • 如果你有一个指针方法,你 >如果你只有一个值,可能不会总是能够来调用它,因为有几个表达式(其结果)是不可寻址的,因此你将无法获得将被使用的指针作为接收者;这样的例子是函数返回值和映射索引表达式。有关详细信息和示例,请参阅如何在Go中存储对操作结果的引用?和如何获得指针函数调用的返回值是什么?(当然,您可以将其分配给本地变量并获取其地址,但这是一个副本,指针方法只能修改此副本而不能)

According to this response to this 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

But in fact I can execute pointer method on non pointer values:

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

So, what is wrong here? Is this a new feature ? or the response to the question is wrong ?

解决方案

You are calling a "pointer method" on a pointer value. In the expression:

c.fourWheels()

c is of type car (non-pointer); since the car.fourWheels() method has a pointer receiver and because the receiver value is a non-pointer and is addressable, it is a shorthand for:

(&c).fourWheels()

This is in Spec: Calls:

If x is addressable and &x's method set contains m, x.m() is shorthand for (&x).m().

The statement:

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

Interpret it like this:

  • If you have a value method, you can always call it: if you have a value, it's ready to be the receiver; and if you have a pointer, you can always dereference it to obtain a value ready to be the receiver.

  • If you have a pointer method, you may not always be able to call it if you only have a value, as there are several expressions (whose result) are not addressable, and therefore you would not be able to obtain a pointer to it that would be used as the receiver; such examples are function return values and map indexing expressions. For details and examples, see How can I store reference to the result of an operation in Go?; and How to get the pointer of return value from function call? (Sure, you could always assign it to a local variable and take its address, but that's a copy and the pointer method could only modify this copy and not the original.)

这篇关于非指针类型的指针方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆