golang - 通过方法来运作 [英] golang - pass method to function

查看:115
本文介绍了golang - 通过方法来运作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我很好奇这是否可以在Go中使用。我有一个多种方法的类型。是否有可能有一个函数,它采用一种方法,并可以调用它的类型?



这是我想要的一个小例子:

package main

import(
fmt


类型Foo int

func(f Foo)A(){
fmt.Println(A)
}
func (f Foo)B(){
fmt.Println(B)
}
func(f Foo)C(){
fmt.Println(C)

$ b func main(){
var f Foo
bar:= func(foo func()){
f.foo()$ (b)
bar(C)
}

Go认为类型 Foo 有一个名为 foo()的方法,而不是用传入的方法名替换它。

解决方案

是的,这是可能的。您有2(3)个选项:



规格:方法表达式



表达式 Foo.A 产生一个相当于一个但带有明确的接收者作为第一个参数;它有签名 func(f Foo)

  var f Foo 
bar:= func(m func(f Foo)){
m(f)
}
bar(Foo.A)
bar(Foo.B)
bar(Foo.C)

这里的方法接收者是明确的。您只需要将方法名称(包含它所属的类型)传递给 bar(),并且在调用它时必须传递实际的接收方: m(f)



按预期输出(在 Go Playground ):

  A 
B
C



Spec:方法值



如果 f 是键入 Foo ,表达式 fA 产生一个类型为 func()隐含接收者值 f

  var f Foo 
bar:= func(m func()){
m()
}
bar(fA)
bar(fB)
bar(fC)

请注意,此处的方法接收器是隐式的,它将保存在传递给 bar(),所以调用它时没有明确指定它: m()



输出是一样的(在

(完整性: Go Playground ) //golang.org/pkg/reflect/rel =noreferrer>反射)



劣于以前的解决方案(包括性能和安全性),但是您可以将该方法的名称作为字符串值传递,然后使用 reflect 程序包通过该名称调用方法。它可能看起来像这样:

  var f Foo 
bar:= func(name string){
('B')
bar(C).BethName(name).Call(nil)
}
bar(A)
bar )

试试这个 Go Goground


I'm curious if this is possible in Go. I have a type with multiple methods. Is it possible to have a function which takes a method and can call it for the type?

Here is a small example of what I would want:

package main

import (
  "fmt"
)

type Foo int

func (f Foo) A() {
    fmt.Println("A")
}
func (f Foo) B() {
    fmt.Println("B")
}
func (f Foo) C() {
    fmt.Println("C")
}

func main() {
    var f Foo
    bar := func(foo func()) {
        f.foo()
    }
    bar(A)
    bar(B)
    bar(C)
}

Go thinks type Foo has a method called foo(), rather than replacing it with the passed in method name.

解决方案

Yes, it's possible. You have 2 (3) options:

Spec: Method expressions

The expression Foo.A yields a function equivalent to A but with an explicit receiver as its first argument; it has signature func(f Foo).

var f Foo
bar := func(m func(f Foo)) {
    m(f)
}
bar(Foo.A)
bar(Foo.B)
bar(Foo.C)

Here the method receiver is explicit. You only pass the method name (with the type it belongs to) to bar(), and when calling it, you have to pass the actual receiver: m(f).

Output as expected (try it on the Go Playground):

A
B
C

Spec: Method values

If f is a value of type Foo, the expression f.A yields a function value of type func() with implicit receiver value f.

var f Foo
bar := func(m func()) {
    m()
}
bar(f.A)
bar(f.B)
bar(f.C)

Note that here the method receiver is implicit, it is saved with the function value passed to bar(), and so it is called without explicitly specifying it: m().

Output is the same (try it on the Go Playground).

(For completeness: reflection)

Inferior to previous solutions (both in performance and in "safeness"), but you could pass the name of the method as a string value, and then use the reflect package to call the method by that name. It could look like this:

var f Foo
bar := func(name string) {
    reflect.ValueOf(f).MethodByName(name).Call(nil)
}
bar("A")
bar("B")
bar("C")

Try this on the Go Playground.

这篇关于golang - 通过方法来运作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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