方法接收器上的 golang 函数别名

golang function alias on method receiver

我可以为常用方法创建方法别名:

func method1() {
    fmt.Println("method1")
}

var Method1 = method1

但不能对方法接收者做同样的事情:

type Person struct {
    Name string
}

func (p *Person) methodReciver() {
    fmt.Println("method reciver")
}

var MethodReciver = methodReciver

在这种情况下,我在第 var MethodReciver = methodReciver 行收到错误:

undefined: methodReciver

完整代码:

package main

import (
    "fmt"
)

type Person struct {
    Name string
}

func method1() {
    fmt.Println("method1")
}

var Method1 = method1

func (p *Person) methodReceiver() {
    fmt.Println("method receiver")
}

var MethodReceiver = methodReceiver

func main() {
    method1()
    Method1()
    p := Person{"Nick"}
    p.methodReceiver()
    p.MethodReceiver()
}

Playground

是否可以为 methodReceiver 创建方法别名?

是的。你可以像这样创建一个别名:

var MethodReceiver = (*Person).methodReceiver

当你调用它时,你必须提供一个指向 person 对象的指针作为第一个参数:

MethodReceiver(&p)

你可以see this in action on the Go Playground.

这个叫做method expressionvar MethodReceiver = (*Person).methodReceiver

Playground

基本上你有两个选择:

1。使用 Method Expression

具有 ReceiverType.MethodName 的形式,它产生函数类型的值:

var MethodReceiver = (*Person).methodReceiver

MethodReceiver 只保存函数引用但 不是 接收者,所以如果你想调用它,你还必须传递一个接收者(类型 *Person) 作为第一个参数:

var p = &Person{"Alice"}
MethodReceiver(p)  // Receiver is explicit: p

2。使用 Method Value

具有 x.MethodName 的形式,其中表达式 x 具有静态类型 T:

var p = &Person{"Bob"}
var MethodReceiver2 = p.methodReceiver

一个方法值也存储了receiver,所以当你调用它时,你不必传递一个receiver给它:

MethodReceiver2()  // Receiver is implicit: p

完整示例

Go Playground 上试用。

type Person struct {
    Name string
}

func (p *Person) printName() {
    fmt.Println(p.Name)
}

var PrintName1 = (*Person).printName

func main() {
    var p1 *Person = &Person{"Bob"}
    PrintName1(p1) // Have to specify receiver explicitly: p1

    p2 := &Person{"Alice"}
    var PrintName2 = p2.printName // Method value, also stores p2
    PrintName2()                  // Implicit receiver: p2
}

输出:

Bob
Alice