## 1 概述
利用反射,不仅可以获取信息,还可以创建实例,执行函数和方法。就是反射代理执行。
<!-- more -->
## 2 创建实例
创建实例的前提是具有 `reflect.Type` 对象,基于此创建实例。使用 `reflect.TypeOf()` 函数,可以获取得到某类型的 `reflect.Type` 对象,演示如下:
```go
typeStu := reflect.TypeOf(Stu{})
s := reflect.New(typeStu)
s.Elem().FieldByName("Name").SetString("Hank") // 利用反射设置结构体字段值
fmt.Println(s.Elem().FieldByName("Name").String()) // Hank
```
我们创建了实例,一直都是通过反射的方式操作的。
## 3 调用函数
如果值反射对象 `reflect.Value` 反射的是函数时,可以通过 `reflect.Value` 调用该函数。使用反射调用函数时,需要将参数使用反射值对象的切片 `[]reflect.Value` 构造后传入 `Call()` 方法中传参。调用完成时,函数的返回值通过 `[]reflect.Value` 返回。
演示如下:
```go
func fn(p1, p2 int) int {
return p1 + p2
}
func main() {
valueFunc := reflect.ValueOf(fn)
paramList := []reflect.Value{
reflect.ValueOf(22),
reflect.ValueOf(20),
}
// 反射调用函数
resultList := valueFunc.Call(paramList)
// 获取第一个返回值, 取整数值
fmt.Println(resultList[0].Int()) // 42
}
```
## 4 调用方法
整体与调用函数一致,额外的需要先通过对象的值反射获取对象方法的反射对象,再使用 `Call()` 调用,示例:
```go
type Stu struct {
Name string
}
func (this *Stu) Fn(p1, p2 int) int {
return p1 + p2
}
func main() {
s := &Stu{"Hank"}
valueS := reflect.ValueOf(s)
method := valueS.MethodByName("Fn")
paramList := []reflect.Value{
reflect.ValueOf(22),
reflect.ValueOf(20),
}
resultList := method.Call(paramList)
fmt.Println(resultList[0].Int()) // 42
}
```
完!
原文出自:[小韩说课](http://www.hellokang.net/go/go-reflect-inoke/)
微信关注:小韩说课
![小韩说课](http://www.hellokang.net/images/wechat_subscription.jpg)
有疑问加站长微信联系(非本文作者))