golang标准库reflect的魔法运用

作者: 从火星来 | 来源:发表于2018-06-01 18:16 被阅读37次

    本文要解决什么问题?

    有时候我们为了简化代码,需要包装使用一些参数数量可变的函数,例如数据库查询用的Query、Exec等函数,你的SQL语句中有多少个“?”,后面就要对应提供多少参数。要包装这样的函数,使用reflect库是唯一的选择。

    实现方法

    废话不多说,下面就说说实质性的内容。

    思路

    总体上就是依靠reflect.Value来实现,一个reflect.Value赋值为要执行的函数,另外一个数组[]reflect.Value用来存储参数,最后使用reflect.Value.Call方法执行函数。

    实例

    咱们就拿最简单的fmt.Println来做例子,给它做一个包装,并且返回它的全部返回值,代码如下:

    func WrapPrintln(arg ...interface{}) (int,error) {
        var f = reflect.ValueOf( fmt.Println )
        var args = make( []reflect.Value, len(arg) )
        for i:=0;i<len(arg);i++ {
        if arg[i]==nil{
            args[i] = reflect.Zero(reflect.TypeOf(errors.New("")))
        }else{
            args[i] = reflect.ValueOf( arg[i] )
        }
        }
        ret := f.Call( args )
        n := ret[0].Interface().(int)
        if ret[1].Interface()!=nil{
            return n,ret[1].Interface().(error)
        } else {
            return n,nil
        }
    }
    

    至于上面的例子为什么要多加一个判断参数是否是nil,是因为reflect.ValueOf(nil)panic,不得已而为之。

    end

    相关文章

      网友评论

        本文标题:golang标准库reflect的魔法运用

        本文链接:https://www.haomeiwen.com/subject/aovksftx.html