go反射
一.反射的概念
Go语言提供了一种机制在运行时更新和检查变量的值,调用变量的方法和变量支持的内在操作,但是在编译时并不知道这些变量的具体类型, 这种机制被称为反射.Go语言中的反射是由 reflect 包提供支持的,它定义了两个重要的类型 Type 和 Value 任意接口值在反射中都可以理解为由 reflect.Type 和 reflect.Value 两部分组成,并且 reflect 包提供了 reflect.TypeOf 和 reflect.ValueOf 两个函数来获取任意对象的 Value 和 Type.
二.reflect包
1.基本操作
type Student struct { Name string `json:"name"` Age int `json:"age"` } var str = "hello" var student Student
-
- 获取变量类型: TypeOf()
// TypeOf returns the reflection Type that represents the dynamic type of i // If i is a nil interface value, TypeOf returns nil. fmt.Println(reflect.TypeOf(str)) // string fmt.Println(reflect.TypeOf(student)) // main.Student
- 获取变量的值: ValueOf()
// ValueOf returns a new Value initialized to the concrete value // stored in the interface i. ValueOf(nil) returns the zero Value. fmt.Println(reflect.ValueOf(str)) // hello fmt.Println(reflect.ValueOf(student)) // { 0} 由于未给变量student赋值,返回对应类型的零值
-
- 获取变量的种类: Kind()
首先要知道reflect包中都有哪些类型:
const ( Invalid Kind = iota Bool Int Int8 Int16 Int32 Int64 Uint Uint8 Uint16 Uint32 Uint64 Uintptr Float32 Float64 Complex64 Complex128 Array Chan Func Interface Map Ptr // 表示指针类型 Slice String Struct UnsafePointer )
示例:
fmt.Println(reflect.TypeOf(str).Kind()) // string fmt.Println(reflect.ValueOf(str).Kind()) // string fmt.Println(reflect.TypeOf(student).Kind()) // struct fmt.Println(reflect.ValueOf(student).Kind()) // structh
-
- 获取结构体标签
structName, _ := reflect.TypeOf(&student).Elem().FieldByName("Name") tagName := structName.Tag.Get("json") fmt.Println(tagName) // name student结构体中Name对应的json标签为name
2. 修改变量的值
type Student struct { Name string `json:"name"` Age int `json:"age"` } var str = "hello" var student = Student{"Bob", 23} // 使用Elem()方法必须使用指针或interface类型 // Elem returns the value that the interface v contains // or that the pointer v points to. // It panics if v's Kind is not Interface or Ptr. // It returns the zero Value if v is nil. reflect.ValueOf(&str).Elem().SetString("world") reflect.ValueOf(&student).Elem().FieldByName("Name").SetString("Lily") fmt.Println(str) // world fmt.Println(student) // {Lily 23}