go反射----3方法

雨痕老师《Go语言学习笔记》

动态调用方法,谈不上有多麻烦。只需按IN列表准备好所需参数即可。

package main

import (
        "fmt"
        "reflect"
)

type X struct{}

func (X) Test(x, y int) (int, error) {
        return x + y, fmt.Errorf("err:%d", x+y)
}
func main() {
        var a X
        v := reflect.ValueOf(&a)
        m := v.MethodByName("Test")
        in := []reflect.Value{
                reflect.ValueOf(1),
                reflect.ValueOf(2), //最后一个字段如果不和}相连,则必须添加,
        }
        out := m.Call(in)
        for _, v := range out {
                fmt.Println(v)
        }
}

输出:

3
err:3

对于变参来说,用CallSlice要更方便一些。

package main

import (
        "fmt"
        "reflect"
)

type X struct{}

func (X) Format(s string, a ...interface{}) string {
        return fmt.Sprintf(s, a...)
}
func main() {
        var a X
        v := reflect.ValueOf(&a)
        m := v.MethodByName("Format")
        out := m.Call([]reflect.Value{
                reflect.ValueOf("%s=%d"),
                reflect.ValueOf("x"),
                reflect.ValueOf(100),
        })
        fmt.Println(out)
        out = m.CallSlice([]reflect.Value{
                reflect.ValueOf("%s=%d"),
                reflect.ValueOf([]interface{}{"x", 100}),
        })
        fmt.Println(out)
}

输出:

[x=100]
[x=100]

无法调用非导出方法,甚至无法获取有效地址。