2016-03-07 67 views
-3

对不起,我再次发布我的问题。如何将结构的方法作为参数传递给使用golang的另一个函数

我在问我的问题之前已经阅读了解决方案。我认为它不能帮助我,因为我的问题是如何传递一个函数作为参数?我不想打电话给它。

我只是想将它传递给我不能修改另一个函数(或者我不希望编辑),我想用一个字符串变量指向功能

funcName := "Go" 
m.set(t.funcName) 

我认为这是从这个问题Call a Struct and its Method by name in Go?

例如不同

我有这样一个功能:

type Context struct{} 
type myclass struct{} 
type Handler func (c *Context) 

func (r *myclass) set(ch Handler) { 

} 

我可以用这样的方式:

type testclass struct {} 
func (t *testclass) Go(c *Context){ 
    println("Hello"); 
} 

t := &testclass{} 
m := &myclass{} 
m.set(t.Go) 

,我的问题是

type testclass struct{} 
func (t *testclass) Go(c *Context){ 
    println("Hello"); 
} 

t := &testclass{} 
m := &myclass{} 

funcName := "Go" 
m.set(t.funcName) 

什么办法可以做到这一点?

反映?还是什么?

如果不可能,还有其他方法可以做到这一点?

谢谢

+2

你想做什么?你为什么想这样做? – peterSO

回答

0

您可以使用反射包通过名称获取方法。下面就来获得Handler给定名称的函数:

func handlerByName(v interface{}, name string) (Handler, error) { 
    m := reflect.ValueOf(v).MethodByName(name) 
    if !m.IsValid() { 
    return nil, errors.New("method not found") 
    } 
    h, ok := m.Interface().(func(*Context)) 
    if !ok { 
    return nil, errors.New("method is not a handler") 
    } 
    return h, nil 
} 

下面介绍如何使用功能:

h, err := handlerByName(t, "Go") 
if err != nil { 
    // handle error 
} 
m.set(h) 

playground example

注意,通过handlerByName返回的功能是反射包装围绕原始功能(谢谢@OneOfOne指出这一点)。与直接调用该函数相比,调用该包装比较慢。

+0

你应该补充说这不是非常习惯(或安全)的代码。如果我们有更多关于“为什么”的背景,OP的代码可能可以避免这种情况。 – elithrar

+0

OP大概不是高级的Go用户。你为什么推荐使用反射? – Volker

+0

@Volker对于给定的任务,反射的适用性与要求的人无关。 –

相关问题