Go语言提供了一种机制,能够在运行时更新变量或检查它们的值、调用它们的方法和它们支持的内在操作,而不需要在编译时就知道这些变量的具体类型。这种机制被称为反射(这里反射的定义和其他语言大体相同)。反射也可以让我们将类型本身作为第一类的值类型处理。
用来获取输入参数接口中的数据的值,如果接口为空则返回0
用来获取输入参数接口中的值的类型,如果接口为空则返回nil
package main
import (
"fmt"
"reflect"
)
type Person struct {
Id int
Name string
}
func (p Person) Say() {
fmt.Printf("p.Name: %v\n", p.Name)
}
func main() {
// 初始化结构体
p := Person{Id: 1, Name: "test"}
p.Say()
// reflect.ValueOf 反射值
items := reflect.ValueOf(&p).Elem()
// 利用属性名称获取值
item := items.FieldByName("Name")
fmt.Printf("%T, %v\n", item, item)
// 利用 kind 获取类型
if item.Kind() == reflect.Invalid {
fmt.Println("不存在的属性")
}
// 遍历结构体属性
typeOfST := items.Type() // 注意获取名称需要获取 reflect.Type 数据
for i := 0; i < items.NumField(); i++ {
itemInFor := items.Field(i)
fmt.Printf("%v : %v\n", typeOfST.Field(i).Name, itemInFor.Interface())
}
// 遍历结构体并调用方法
// 注意 func(p *...){} 指针模式无法获取方法
for ii := 0; ii < items.NumMethod(); ii++ {
fmt.Printf("typeOfST.Method(ii).Name: %v\n", typeOfST.Method(ii).Name)
items.Method(ii).Call(nil)
//fmt.Printf("方法 %v\n", method)
}
}