go语言利用reflect存储函数和参数
2018-04-26 本文已影响37人
从火星来
go语言利用reflect存储函数和参数
本文提供go语言中一种存储任意类型函数和参数的方法。
源代码链接:https://gitee.com/rocket049/golang_test/tree/master/src/funcs
思路
利用reflect.Value类型存储多个任意类型的函数和任意类型的参数,以便在其他位置和时机执行。
导入包
存储类型使用 list.List,因此需要导入 container/list 和 reflect 两个包。
代码如下:
import(
"container/list"
"reflect"
)
定义一个可执行结构
自定义结构体theCallable用于存储任意类型的函数和参数。
代码如下:
type theCallable struct{
f reflect.Value //存储函数
args []reflect.Value //存储参数
}
定义一个列表
自定义结构体FuncList用于存储任意数量的theCallable。
代码如下:
type FuncList struct{
func_list *list.List
}
初始化函数
函数NewFuncList用于初始化一个FuncList的指针。
代码如下:
func (self *FuncList)Init(){
self.func_list = new(list.List)
self.func_list.Init()
}
给FuncList添加Add和Run方法
FuncList对象的Add方法用于加入函数,Run方法用于顺序执行内部存储的函数。
代码如下:
// Add( func,args... ):成功加入后返回 true ,出错的话返回 false
func (self *FuncList)Add( f interface{} ,args... interface{} ) bool {
var call1 *theCallable = new( theCallable )
call1.f = reflect.ValueOf( f )
t := call1.f.Type()
if t.Kind()==reflect.Func {
call1.args = make( []reflect.Value, len(args) )
for i:=0;i<len(args);i++ {
call1.args[i] = reflect.ValueOf( args[i] )
}
self.func_list.PushBack( call1 )
return true
} else {
return false
}
}
// Run():顺序执行存储在内部的函数,然后清除列表
func (self *FuncList)Run(){
var call1 *theCallable
for e:=self.func_list.Front();e!=nil;e=e.Next(){
call1,_ = e.Value.(*theCallable)
call1.f.Call( call1.args )
}
self.func_list.Init()
}
用例
testx函数的参数为数量不定的int类型,用于测试。
代码如下:
func testx(args... int){
fmt.Println("testx 参数量:",len(args))
for i:=0;i<len(args);i++{
fmt.Println(args[i])
}
}
func main(){
fl := NewFuncList()
ok := fl.Add(testx)
fmt.Println("Add(testx)",ok)
ok = fl.Add(testx,1)
fmt.Println("Add(testx,1)",ok)
ok = fl.Add(testx,4,5)
fmt.Println("Add(testx,4,5)",ok)
fl.Add(testx,9,4,6)
fmt.Println("Add(testx,9,4,6)",ok)
fl.Run()
fl.Run() //第二次执行时内部列表已经空了,不会重复执行
}
输出如下:
Add(testx) true
Add(testx,1) true
Add(testx,4,5) true
Add(testx,9,4,6) true
testx 参数量: 0
testx 参数量: 1
1
testx 参数量: 2
4
5
testx 参数量: 3
9
4
6
结束