golang反射中函数和方法的调用
2013-07-14 23:26
288 查看
golang反射中函数和方法的调用
上一篇文章说到了golang中的反射的一些基本规则,重点就是文章中最后的三点,但是这篇文章并没有说如何在反射中调用函数和方法,这就是接下来要谈的。反射中调用函数
众所周知,golang中的函数是可以像普通的int、float等类型变量那样作为值的,例如:package main import "fmt" func hello() { fmt.Println("Hello world!") } func main() { hl := hello hl() }
prints:
hello world!
既然函数可以像普通的类型变量一样可以的话,那么在反射机制中就和不同的变量一样的,在反射中函数和方法的类型(Type)都是reflect.Func,如果要调用函数的话,可以通过Value的Call方法,例如:
func main() { hl := hello fv := reflect.ValueOf(hl) fmt.Println("fv is reflect.Func ?",fv.Kind() == reflect.Func) fv.Call(nil) }
prints:
fv is reflect.Func? true
hello world!
Value的Call方法的参数是一个Value的slice,对应的反射函数类型的参数,返回值也是一个Value的slice,同样对应反射函数类型的返回值。通过这个例子,相信你一看就明白了:
func prints(i int) string { fmt.Println("i =",i) return strconv.Itoa(i) } func main() { fv := reflect.ValueOf(prints) params := make([]reflect.Value,1) //参数 params[0] := reflect.ValueOf(20) //参数设置为20 rs := fv.Call(params) //rs作为结果接受函数的返回值 fmt.Println("result:",rs[0].Interface().(string)) //当然也可以直接是rs[0].Interface() }
prints:
i = 20 result: 20
反射中调用方法
上面说了在反射中调用函数的例子,接下来我们要谈谈反射中方法的调用。函数和方法可以说其实本质上是相同的,只不过方法与一个“对象”进行了“绑定”,方法是“对象”的一种行为,这种行为是对于这个“对象”的一系列操作,例如修改“对象”的某个属性,例如如下:type MyType struct { i int name string } func (mt *MyType) SetI(i int) { mt.i = i } func (mt *MyType) SetName(name string) { mt.name = name } func (mt *MyType) String() string { return fmt.Sprintf("%p",mt) + "--name:" + mt.name + " i:" + strconv.Itoa(mt.i) }
好了,现在类型和其对应的方法都已经准备好了,那接下来就是如何使用的问题了,我们有了上面调用函数的经验,只需要再了解一点知识就可以使用了,这一点知识就是Method和MethodByName的API,好了,现在都准备好了,我们就看看如何使用吧。
func main() { myType := &MyType{22,wowzai} //fmt.Println(myType) //就是检查一下myType对象内容 //println("---------------") mtV := reflect.ValueOf(&myType).Elem() fmt.Println("Before:",mtV.MethodByName("String").Call(nil)[0]) params := make([]reflect.Value,1) params[0] = reflect.ValueOf(18) mtV.MethodByName("SetI").Call(params) params[0] = reflect.ValueOf("reflection test") mtV.MethodByName("SetName").Call(params) fmt.Println("After:",mtV.MethodByName("String").Call(nil)[0]) }
prints:
Before: address:0x18245050--name:wowzai i:22 After: address:0x18245050--name:reflection test i:18
需要注意的是上面打印的地址是对象在内存的地址,如果你也运行了这段代码,结果这个地址应该是不同的。
咦,就这样结束了吗?当然不是,细心的读者会发现上面提到的Method好像没用到啊,恩,是的,聪明的你一看API的介绍我相信你就知道如何将上面的代码转换成用Method方法达到同样的效果:
mtV := reflect.ValueOf(&myType).Elem() fmt.Println("Before:",mtV.Method(2).Call(nil)[0]) params = make([]reflect.Value,1) params[0] = reflect.ValueOf(18) mtV.Method(0).Call(params) params[0] = reflect.ValueOf("reflection test") mtV.Method(1).Call(params) fmt.Println("After:",mtV.Method(2).Call(nil)[0])
打印的效果和上面的例子相同(地址可能不同),嗯,到这里基本上反射中函数和方法的调用基本说完了,可是真的结束了?是否还有其他办法呢?嗯,聪明的你总能想得到的。
---如有错误,欢迎指正---
相关文章推荐
- Go - 反射中 函数 和 方法 的调用 - v.Call()
- golang通过反射动态调用方法
- Golang 反射调用结构体属性、Tag、方法总结
- 黑马程序员—反射调用main方法的问题总结(涉及可变参数)(反射参数是一个数组的函数要小心)
- golang通过反射调用方法
- 反射方法去调用某脚本的函数
- 利用golang的反射包,实现根据函数名自动调用函数。
- golang通过反射使用json字符串调用struct的指定方法及返回json结果
- Object-C基础(10)——异常处理、反射、动态调用方法与内存回收
- golang中的RPC调用服务器方法
- 函数调用参数改变的两种方法——指针与引用
- Java调用private方法—Java中的类反射机制
- java 反射调用类的方法 http://weiliuhong1.iteye.com/blog/1222381
- 用反射方法使用户控件动态调用父页面的方法
- 如何通过C#.NET中的反射机制来创建C#.NET泛型类的实例,并调用其方法??
- Java的反射机制-动态调用对象的方法
- 反射机制进行动态调用的两种创建方法实例与hama中的反射机制
- java使用反射机制调用方法
- web developer tips (83):通过反射从堆栈里获取调用的方法名称
- JS中跨页面调用变量和函数的方法(例如a.js 和 b.js中互相调用)