我在这里找到了一个名为MethodByName()
的函数http://golang.org/pkg/reflect/#Value.MethodByName,但它并不是我想要的!(也许是因为我不知道如何使用它。我找不到任何使用它的例子)。我想要的是:
type MyStruct struct {
//some feilds here
}
func (p *MyStruct) MyMethod {
println("My statement.");
}
CallFunc("MyStruct", "MyMethod");
//print out "My statement."
所以我猜,首先我需要像StructByName()
这样的东西,然后在MethodByName()
中使用它,对吗?
发布于 2011-11-13 01:49:59
要在对象上调用方法,首先使用reflect.ValueOf
。然后按名称查找该方法,最后调用找到的方法。例如:
package main
import "fmt"
import "reflect"
type T struct {}
func (t *T) Foo() {
fmt.Println("foo")
}
func main() {
var t T
reflect.ValueOf(&t).MethodByName("Foo").Call([]reflect.Value{})
}
发布于 2018-11-14 12:22:28
具有错误处理功能的gist调用结构方法
// Invoke - firstResult, err := Invoke(AnyStructInterface, MethodName, Params...)
func invoke(any interface{}, name string, args ...interface{}) (reflect.Value, error) {
method := reflect.ValueOf(any).MethodByName(name)
methodType := method.Type()
numIn := methodType.NumIn()
if numIn > len(args) {
return reflect.ValueOf(nil), fmt.Errorf("Method %s must have minimum %d params. Have %d", name, numIn, len(args))
}
if numIn != len(args) && !methodType.IsVariadic() {
return reflect.ValueOf(nil), fmt.Errorf("Method %s must have %d params. Have %d", name, numIn, len(args))
}
in := make([]reflect.Value, len(args))
for i := 0; i < len(args); i++ {
var inType reflect.Type
if methodType.IsVariadic() && i >= numIn-1 {
inType = methodType.In(numIn - 1).Elem()
} else {
inType = methodType.In(i)
}
argValue := reflect.ValueOf(args[i])
if !argValue.IsValid() {
return reflect.ValueOf(nil), fmt.Errorf("Method %s. Param[%d] must be %s. Have %s", name, i, inType, argValue.String())
}
argType := argValue.Type()
if argType.ConvertibleTo(inType) {
in[i] = argValue.Convert(inType)
} else {
return reflect.ValueOf(nil), fmt.Errorf("Method %s. Param[%d] must be %s. Have %s", name, i, inType, argType)
}
}
return method.Call(in)[0], nil
}
发布于 2019-01-08 21:01:49
package main
import (
"fmt"
"reflect"
)
type Log struct {
Path string
Level string
}
func (l *Log) Conversion(i interface{}) {
if data, ok := i.(*Log); ok {
if data != nil {
if len(data.Path) > 0 {
l.Path = data.Path
}
if len(data.Level) > 0 {
l.Level = data.Level
}
}
}
}
type Storage struct {
Type string
ServerList []string
}
func (s *Storage) Conversion(i interface{}) {
if data, ok := i.(*Storage); ok {
if data != nil {
if len(data.Type) > 0 {
s.Type = data.Type
}
}
}
}
type Server struct {
LogConfig *Log
StorageConfig *Storage
}
func main() {
def := Server{
LogConfig: &Log{
Path: "/your/old/log/path/",
Level: "info",
},
StorageConfig: &Storage{
Type: "zookeeper",
ServerList: []string{"127.0.0.1:2181"},
},
}
fmt.Println(def)
cur := Server{
LogConfig: &Log{
Path: "/your/new/log/path/",
Level: "debug",
},
StorageConfig: &Storage{
Type: "etcd",
ServerList: []string{"127.0.0.1:2379"},
},
}
fmt.Println(cur)
defV := reflect.ValueOf(def)
curV := reflect.ValueOf(cur)
for k := 0; k < defV.NumField(); k++ {
in := make([]reflect.Value, 1)
in[0] = reflect.ValueOf(curV.Field(k).Interface())
defV.Field(k).MethodByName("Conversion").Call(in)
}
fmt.Println(def.LogConfig)
fmt.Println(def.StorageConfig)
}
https://stackoverflow.com/questions/8103617
复制相似问题