golang reflect动态调用函数

今天把reflect包由学习了一遍,就是通过映射来动态的调用方法。例子比较简单,但很全。

package test


import (
	"context"
	"fmt"
	"reflect"
	"go_vendors/github.com/go-errors/errors"
)

//上下文,传递一些变量
type Model struct {
	Ctx  context.Context
}

//字典,包含所有的对象
var Models = make(map[string]reflect.Type,0)

func init() {
	Models["First"] = reflect.TypeOf(First{})
	Models["Second"] = reflect.TypeOf(Second{})
}


type Param struct {
	Name 	string
	Method 	string
}

type First struct {
	Model
}


func (self *First) Test(param Param) (err error) {
	fmt.Println("first test")
	return
}



type Second struct {
	Model
}

func (self *Second) Stest(param Param) (err error) {
	fmt.Println("second test")
	return
}




func Execute(param Param) (err error) {
	name,methodname := param.Name,param.Method
	if _,ok := Models[name];!ok {
		fmt.Println("dose not exist correspond name struct")
		err = errors.New("no exist")
		return
	}
	defer func(){
		if err := recover();err != nil {
			fmt.Println("PanicError",err)
		}
	}()

	ctx := reflect.ValueOf(context.Background())
    //和内置的new比较像
	instance := reflect.New(Models[name])
	field := instance.Elem().FieldByName("Ctx")
	if field.CanSet() {
		instance.Elem().FieldByName("Ctx").Set(ctx)
	}
	method := instance.MethodByName(methodname)
	if !method.IsValid() {
		err = errors.New("no method or method is not valid")
		return
	}
	params := make([]reflect.Value,0)
   //必须用reflect.Value包装
	params = append(params,reflect.ValueOf(param))
	method.Call(params)
	return
}

--------EOF---------
微信分享/微信扫码阅读