1 Star 0 Fork 0

rocket049 / documents

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
reflect库魔法运用.md 1.41 KB
一键复制 编辑 原始数据 按行查看 历史
rocket049 提交于 2018-06-11 20:46 . del

#golang标准库reflect的魔法运用

##本文要解决什么问题?

有时候我们为了简化代码,需要包装使用一些参数数量可变的函数,例如数据库查询用的QueryExec等函数,你的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

1
https://gitee.com/rocket049/documents.git
git@gitee.com:rocket049/documents.git
rocket049
documents
documents
master

搜索帮助