首页 >后端开发 >Golang >为什么 Go 在调用指针接收器方法时会隐式取消引用?

为什么 Go 在调用指针接收器方法时会隐式取消引用?

DDD
DDD原创
2024-12-02 07:03:10800浏览

Why Does Go Implicitly Dereference When Calling Pointer Receiver Methods?

Go 方法集:调用指针类型和接收器的方法

Go 方法集的一个经常讨论的方面在尝试调用时出现类型为 T 的变量上具有接收器类型 T 的方法。Go 规范规定,方法集T 包括接收者类型为 *T 的方法和接收者类型为 T 的方法。

冲突的推论

但是,以下示例演示了此推论可以似乎违反直觉:

package main

import (
    "fmt"
    "reflect"
)

type User struct{}

func (self *User) SayWat() {
    fmt.Println(self)
    fmt.Println(reflect.TypeOf(self))
    fmt.Println("WAT\n")
}

func main() {
    var user User = User{}

    fmt.Println(reflect.TypeOf(user), "\n")

    user.SayWat()
}

编译器推理

编译器推断 user.SayWat() 调用了接收者类型为 *T 的方法,尽管变量 user 的类型为 T。这种行为是由编译器自动插入 & 引起的,地址运算符。本质上,它重写了对 (&user).SayWat().

调用指针类型的方法

重要的是要澄清,虽然看起来指针类型的方法是在类型 T 的变量上调用的,但这并不严格正确。编译器使用 *T 类型的接收器,&user 对 T 的解引用是隐式操作。

隐式解引用的例外

但是,这个隐式取消引用并不适用于所有情况。在返回值(不可寻址)上调用带有指针接收器的方法将导致编译时错误,例如:

func aUser() User {
    return User{}
}

...

aUser().SayWat()

错误消息

cannot call pointer method on aUser()
cannot take the address of aUser()

以上是为什么 Go 在调用指针接收器方法时会隐式取消引用?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn