## 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/)
微信關注:小韓說課
