上一篇文章 说到了 Golang 中的反射的一些基本规则,重点就是文章中最后的三点,但是这篇文章并没有说如何在反射中调用函数和方法,这就是接下来要说的。

反射中调用 函数

众所周知,Golang 中的函数是可以像普通的 int、float 等类型变量那样作为值的,例如:

package mainimport "fmt"func hello() {fmt.Println("Hello world!")
}func main() {hl := hellohl()
}

prints:

hello world!

既然函数可以像普通的类型变量一样可以的话,那么在反射机制中就和不同的变量是一样的,在反射中 函数 和 方法 的类型(Type)都是 reflect.Func,如果要调用函数的话,可以通过 Value 的 Call() 方法,例如:

func main() {hl := hellofv := 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)                    // 参数设置为20rs := fv.Call(params)                              // rs作为结果接受函数的返回值fmt.Println("result:", rs[0].Interface().(string)) // 当然也可以直接是 rs[0].Interface()
}

prints:

i = 20
result: 20

反射中调用 方法

上面说了在反射中调用函数的例子,接下来我们要谈谈反射中方法的调用。函数和方法可以说其实本质上是相同的,只不过方法与一个“对象”进行了“绑定”,方法是“对象”的一种行为,这种行为是对于这个“对象”的一系列操作,例如修改“对象”的某个属性,如下所示:

type MyType struct {i    intname 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, "golang"}//fmt.Println(myType)     // 就是检查一下myType对象内容//println("---------------")mtV := reflect.ValueOf(&myType).Elem()// 也可以使用//mtV := reflect.ValueOf(myType)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:golang i 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])

参考:

http://golang.org/doc/articles/laws_of_reflection.html

http://blog.csdn.net/wowzai/article/details/9327405

Go - 反射中 函数 和 方法 的调用 - v.Call()相关推荐

  1. python中怎么调用函数_浅谈Python中函数的定义及其调用方法

    一.函数的定义及其应用 所谓函数,就是把具有独立功能的代码块组织成为一个小模块,在需要的时候调用函数的使用包含两个步骤 1.定义函数–封装独立的功能 2.调用函数–享受封装的成果 函数的作用:在开发时 ...

  2. python函数定义及调用-浅谈Python中函数的定义及其调用方法

    一.函数的定义及其应用 所谓函数,就是把具有独立功能的代码块组织成为一个小模块,在需要的时候调用函数的使用包含两个步骤 1.定义函数�C封装独立的功能 2.调用函数�C享受封装的成果 函数的作用:在开 ...

  3. python中函数和方法的区别

    本篇内容主要介绍从几个维度来介绍下python中函数和方法的区别: 首先,从分类的角度来分析. (1)函数的分类: 内置函数:python内嵌的一些函数. 匿名函数:一行代码实现一个函数功能. 递归函 ...

  4. java中函数和方法区别_java中函数和方法的区别是什么?

    java中函数和方法的区别是什么? 面向对象的语言叫方法 面向过程的语言叫函数 在java中没有函数这么一说,只有方法一说.实际上方法就是函数,函数就是方法,只是在不同的语言不同的称呼而已. [推荐教 ...

  5. JavaScript中函数和方法区别

    相对于其他的编程语言,JavaScript可能是一个奇行种.其中我觉得最有必要提到的是JS中函数与方法的差异. 早期的JS中并没有真正意义上的方法的概念,所谓的方法只是用JS通过this对上下文做出特 ...

  6. python中函数的定义包括_python中函数的定义及调用

    python中函数的定义及使用方法 1.函数的概念:函数是将具有独立功能的代码块组织为一个整体,使其具有特殊功能的代码集; 2.函数的作用:使用函数可以加强代码的复用性,提高程序编写的效率; 3.函数 ...

  7. js中 函数和方法的区别:转载于黑泽君

    js中 函数和方法的区别 在javascript中的解释为: 函数(function)是可以执行的javascript代码块,由javascript程序定义或javascript实现预定义.函数可以带 ...

  8. python中的方法和函数的区别_Python中函数和方法的区别

    在Python中函数和方法是有区别的. 区别一所处的位置:函数是直接写文件中而不是class中,方法是只能写在class中. 区别二定义的方式: 1.函数定义的方式 def关键字  然后接函数名 再是 ...

  9. matlab 定义string_[整理]Matlab中函数定义方法

    Matlab中函数定义方法 Matlab自定义函数的六种方法 n1.函数文件+调用函数(命令)文件:需单独定义一个自定义函数的M文件: n2.函数文件+子函数:定义一个具有多个自定义函数的M文件: n ...

最新文章

  1. pandas编写自定义函数、使用apply函数应用自定义函数基于Series数据生成新的dataframe
  2. 这个播放量200万的视频燃爆了!它讲透了:希尔伯特计划是如何被哥德尔与图灵“打脸”的?...
  3. python向端口发出数据_Python写的简单的端口监听,显示端口上收到的数据,TCP的...
  4. git查看某个文件的修改历史
  5. 怎么汇报一周开发工作情况_如何在没有经验的情况下获得第一份开发人员工作
  6. Loadrunner11完美破解小笔记
  7. 35. 复杂链表的复制
  8. 并发 - 生产者消费者的问题
  9. 一文读懂Python web框架和web服务器之间的关系
  10. linux 写一个包含test的脚本程序,linux的test命令及相关shell脚本详解
  11. Hive自定义函数UDF、UDAF、UDTF
  12. python从入门到精通 明日科技 电子书-【明日科技+python】百度云下载 - 云盘精灵...
  13. Cassandra 之旅 (二) Getting Started
  14. 【Javascript】学习指南
  15. 把一个base64编码的图片绘制到canvas (canvas的图片在转成dataurl)
  16. C#路径中使用斜杠/和反斜杠\的区别
  17. android q状态栏,用腻了导航栏?在一加Android Q beta中强行开启全面屏手势
  18. 长春有学计算机的中专吗,长春比较好的中专学校
  19. 使用HMMER搜索PFam
  20. Oracle 数据统计计算

热门文章

  1. 人工智能如何落地安防?需先迈过算力这一关
  2. 创建细分客户的无监督学习项目
  3. Python五种常见的算法,你都了解么
  4. 使用元学习和推理改善您的模型!
  5. 科普丨深度神经网络与生命的意义
  6. 理解深度学习中的学习率及多种选择策略
  7. 疫情中的人工智能和大数据“社会实验”,将如何影响我国经济社会发展
  8. 【智能驾驶】自动驾驶深度感知技术对车和行人的检测
  9. ​忆阻器会成为“存储墙”的破局者么
  10. 透视世界人工智能发展