Go_反射
反射 : 在运行时动态获取变量相关信息
reflect包
reflect.TypeOf 获取变量的类型, 返回reflect.Type类型
func TypeOf(i interface{}) Type{}
reflect.ValueOf, 获取变量的值, 返回reflect.Value类型
func ValueOf(i interface{}) Value {}
reflect.Value.King, 获取变量类别, 返回一个常量
func (v Value) Kind() Kind {}
reflect.Value.Interface(), 转化成interface{}类型
func (v Value) Interface() (i interface{}) {}
测试
package main
import (
"fmt"
"reflect"
)
func test(b interface{}){
t:= reflect.TypeOf(b)
fmt.Println(t) // int 能得到具体的类型
v := reflect.ValueOf(b) // Value类型有许多的方法, Value.Kind() 获得类别
kd := v.Kind()
if kd != reflect.Struct{
fmt.Println("这不是个结构体")
// reflect.Struct是一个常量, 可以通过kd和他来判断传进来的是不是结构体, 还有其他类型
}
}
func main(){
var a int = 200
test(a)
}
Value取值修改
func test(b interface{}){
t:= reflect.TypeOf(b)
fmt.Println(t) // int 能得到具体的类型
v := reflect.ValueOf(b) // Value类型有许多的方法, Value.Kind() 获得类别
v.Int() // 取值, 对应类型
v.Elem().Int() // 指针取值, 对应类型
v.SetInt(100) // 非指针修改, 对应类型
v.Elem().SetInt(100) // 指针修改, 对应类型
}
操作字段与方法
根据名称获取
package main
import (
"fmt"
"reflect"
)
type Student struct{
name string
age int
}
func (stu Student) Run(){
fmt.Println("跑起来吧")
}
func test(b interface{}){
t:= reflect.TypeOf(b)
fmt.Println(t) // int 能得到具体的类型
val := reflect.ValueOf(b) // Value类型有许多的方法, Value.Kind() 获得leibie
fmt.Println(val.FieldByName("name").String())
val.MethodByName("Run").Call(nil)
}
func main(){
var a Student
a = Student{"王二小", 18}
test(a)
}
循环获取
字段
package main
import (
"fmt"
"reflect"
)
type AA struct{
name string
age int
}
func test(b interface{}){
t:= reflect.TypeOf(b)
fmt.Println(t) // int 能得到具体的类型
val := reflect.ValueOf(b) // Value类型有许多的方法, Value.Kind() 获得类别
for i:=0;i<val.NumField();i++{ // 获取类型的字段数量,
if val.Field(i).Kind() == reflect.Int{ // 取到字段并且判断类别
fmt.Println(val.Field(i).Int())
} // 得到的也是Value对象
}
}
func main(){
var a AA
a = AA{"王二小", 18}
test(a)
}
方法
package main
import (
"fmt"
"reflect"
)
type Student struct{
name string
age int
}
func (stu Student) Run(){
fmt.Println("跑起来吧")
}
func test(b interface{}){
t:= reflect.TypeOf(b)
fmt.Println(t) // int 能得到具体的类型
val := reflect.ValueOf(b) // Value类型有许多的方法, Value.Kind() 获得leibie
fmt.Println(val.NumMethod())
for i:=0;i<val.NumMethod();i++{
fmt.Println(val.Method(i).Call(nil)) // 拿到函数并调用
}
}
func main(){
var a Student
a = Student{"王二小", 18}
test(a)
}
通过反射访问Tag
package main
import (
"fmt"
"reflect"
)
type Student struct{
Name string `json:"name"`
Age int `json:"age"`
}
func (stu Student) Run(){
fmt.Println("跑起来吧")
}
func test(b interface{}){
val := reflect.TypeOf(b)
// val.Elem().FieldByName("Name").Tag.Get("json")
fmt.Println(val.Field(1).Tag.Get("json")) // 获取字段Tag的json内容, 可以用FieldByName,不过他有俩返回值
}
func main(){
var a Student
a = Student{"王二小", 18}
test(a)
}

浙公网安备 33010602011771号