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

Max*_*mov 8 alias go

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

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

var Method1 = method1
Run Code Online (Sandbox Code Playgroud)

但是对于方法接收器不能做同样的事情:

type Person struct {
    Name string
}

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

var MethodReciver = methodReciver
Run Code Online (Sandbox Code Playgroud)

在这种情况下,我得到了错误在线var MethodReciver = methodReciver:

undefined: methodReciver
Run Code Online (Sandbox Code Playgroud)

完整代码:

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()
}
Run Code Online (Sandbox Code Playgroud)

操场

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

icz*_*cza 23

基本上你有2个选择:

1.使用方法表达式

其形式为ReceiverType.MethodName,它产生一个函数类型的值:

var MethodReceiver = (*Person).methodReceiver
Run Code Online (Sandbox Code Playgroud)

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

var p = &Person{"Alice"}
MethodReceiver(p)  // Receiver is explicit: p
Run Code Online (Sandbox Code Playgroud)

2.使用方法值

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

var p = &Person{"Bob"}
var MethodReceiver2 = p.methodReceiver
Run Code Online (Sandbox Code Playgroud)

方法值也存储接收器,因此当您调用它时,您不必将接收器传递给它:

MethodReceiver2()  // Receiver is implicit: p
Run Code Online (Sandbox Code Playgroud)

完整的例子

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
}
Run Code Online (Sandbox Code Playgroud)

输出:

Bob
Alice
Run Code Online (Sandbox Code Playgroud)


Dav*_*son 10

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

var MethodReceiver = (*Person).methodReceiver
Run Code Online (Sandbox Code Playgroud)

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

MethodReceiver(&p)
Run Code Online (Sandbox Code Playgroud)

您可以在Go Playground上看到这一点.