< >
    首页

    go语言利用reflect存储函数和参数

    本文提供go语言中一种存储任意类型函数和参数的方法。 源代码链接:https://gitee.com/rocket049/golang_test/tree/master/src/funcs

    思路

    利用*reflect.Value*类型存储多个任意类型的函数和任意类型的参数,以便在其他位置和时机执行。

    导入包

    存储类型使用 *list.List*,因此需要导入 container/listreflect 两个包。 代码如下:

    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
    

    结束

    有收获请打赏作者:
    备案号:苏ICP备19034936号/ 苏ICP备19034936号-1    站长邮箱:fuhuizn@163.com   版权所有

    苏公网安备 32050702010684号

    Powered by MarkdownWeb