go语言—反射reflect
- 在go语言标准库中
reflect
包提供了运行时反射
机制,所谓的运行时反射
,就是程序运行过程中动态操作结构体; - 当变量存储结构体属性名称,想要对结构体这个属性赋值或查看时,就可以使用反射;
- 反射还可以用作判断变量类型;
reflect
中最重要的两个类型:reflect.Type
和reflect.Value
;- 获取到
Type
和Value
的函数: reflect.TypeOf(interface{})
返回Type
,reflect.ValueOf(interface{})
返回Value
; - 反射时获取的如果是指针类型,需要使用Elem()来获取指针指向地址的封装,地址的值必须通过调用
Elem()
才可以继续操作; - 如果需要修改属性的内容,要求结构体中属性名称首字母大写才可以设置;
- 结构体支持标记(
tag
),标记通常都是通过反射技术获取到,结构体标记语法:type 结构体名称 struct {
属性名 类型 `key:"Value"`
}
package main
import (
"fmt"
"reflect"
)
func main() {
getTags()
}
func judgeType() {
a := 2.4
b := 12
c := "hello world"
fmt.Println(reflect.TypeOf(a))
fmt.Println(reflect.ValueOf(a))
fmt.Println(reflect.TypeOf(b))
fmt.Println(reflect.ValueOf(b))
fmt.Println(reflect.TypeOf(c))
fmt.Println(reflect.ValueOf(c))
}
type People4 struct {
Id int `xml:"id"`
Name string `xml:"name"`
}
func getStructValue() {
p1 := People4{1001, "张三"}
v := reflect.ValueOf(p1)
fmt.Println("属性个数: ", v.NumField())
fmt.Println(v.FieldByIndex([]int{0}))
fmt.Println(v.FieldByIndex([]int{1}))
fmt.Println(v.Field(0).Int())
fmt.Println(v.Field(1).String())
idValue := v.FieldByName("Id")
fmt.Println(idValue.Kind().String())
}
func setAttr() {
p2 := new(People4)
v := reflect.ValueOf(p2).Elem()
content := "Id"
name := "Name"
fmt.Println(v.FieldByName(content).CanSet())
v.FieldByName(content).SetInt(1003)
v.FieldByName(name).SetString("李四")
fmt.Println(p2)
}
func getTags() {
t:= reflect.TypeOf(People4{})
fmt.Println(t.FieldByName("Name"))
name, _ := t.FieldByName("Name")
fmt.Println(name)
fmt.Println(name.Tag)
fmt.Println(name.Tag.Get("xml"))
}