go语言反射reflection
反射:可以在运行时动态获取变量的相关信息
go语言中通过reflect
包操作反射
获取基本类型
reflect.TypeOf() //获取变量的类型,返回reflect.Type类型
reflect.ValueOf() //获取变量的值,返回reflect.Value类型
reflect.Value.Kind() //获取变量的类别,返回一个常量
reflect.Value.Interface() //转换成interface{}类型
例子:
package main
import (
"fmt"
"reflect"
)
func main() {
var a float64 = 3.14
fmt.Println("type: ", reflect.TypeOf(a))
b := reflect.ValueOf(a)
fmt.Println("value: ", b)
fmt.Println("type: ", b.Type())
fmt.Println("kind: ", b.Kind())
fmt.Println("value: ", b.Float())
fmt.Println(b.Interface())
fmt.Printf("value is %5.2e\n", b.Interface())
c := b.Interface().(float64)
fmt.Println(c)
}
输出结果:
type: float64
value: 3.14
type: float64
kind: float64
value: 3.14
3.14
value is 3.14e+00
3.14
获取结构体
例子:
package main
import (
"fmt"
"reflect"
)
type Member struct {
Name string
Age int
}
func testStruct(b interface{}) {
t := reflect.TypeOf(b)
fmt.Println("type: ", t)
v := reflect.ValueOf(b)
fmt.Println("value: ", v)
k := v.Kind()
fmt.Println("kind: ", k)
iv := v.Interface()
mem, ok := iv.(Member)
if ok {
fmt.Printf("%v %T\n", mem, mem)
}
}
func main() {
var a = Member{
Name: "Musker",
Age: 22,
}
testStruct(a)
}
输出结果:
type: main.Member
value: {Musker 22}
kind: struct
{Musker 22} main.Member
Elem反射操作基本类型
用来获取指针指向的变量,相当于: var a *int;
例子
package main
import (
"fmt"
"reflect"
)
func testEm(a interface{}) {
val := reflect.ValueOf(a)
ve := val.Elem()
ve.SetInt(100)
b := ve.Int()
fmt.Printf("get value interface{} %d\n", b)
fmt.Printf("string val: %d\n", val.Elem().Int())
}
func main() {
var a int = 1
fmt.Println("before: ", a)
testEm(&a)
fmt.Println("after: ", a)
}
输出结果:
before: 1
get value interface{} 100
string val: 100
after: 100
反射调用结构体方法
例子:
package main
import (
"fmt"
"reflect"
)
type Student struct {
Name string
Age int
Score float32
}
func (s Student) Print() {
fmt.Println(s)
}
func (s Student) Set(name string, age int, score float32) {
s.Name = name
s.Age = age
s.Score = score
}
func TestStruct(a interface{}) {
val := reflect.ValueOf(a)
kd := val.Kind()
fmt.Println(val, kd)
// 判断是否为struct
if kd != reflect.Struct {
fmt.Println("expect struct")
return
}
// 获取字段数量
fields := val.NumField()
fmt.Printf("strut has %d field\n", fields)
// 获取字段类型
for i := 0; i < fields; i++ {
fmt.Printf("%d %v\n", i, val.Field(i).Kind())
}
// 获取方法数量
methods := val.NumMethod()
fmt.Printf("struct has %d methods\n", methods)
// 反射调用Print方法
var params []reflect.Value
// params为参数列表,此处为[]
val.Method(0).Call(params)
}
func main() {
var a Student = Student{
Name: "Musker",
Age: 22,
Score: 99.99,
}
TestStruct(a)
}
输出结果:
{Musker 22 99.99} struct
strut has 3 field
0 string
1 int
2 float32
struct has 2 methods
{Musker 22 99.99}
Elem反射操作结构体
例子:
package main
import (
"fmt"
"reflect"
)
type Student struct {
Name string
Age int
Score float32
}
func (s Student) Print() {
fmt.Println(s)
}
func TestStruct(a interface{}) {
val := reflect.ValueOf(a)
kd := val.Kind()
fmt.Println(val, kd)
if kd != reflect.Ptr && val.Elem().Kind() == reflect.Struct {
fmt.Println("expect struct")
return
}
// 获取字段数量
fields := val.Elem().NumField()
fmt.Printf("struct has %d field\n", fields)
//获取字段类型
for i := 0; i < fields; i++ {
fmt.Printf("%d %v\n", i, val.Elem().Field(i).Kind())
}
// 获取方法数量
methods := val.Elem().NumField()
fmt.Printf("struct has %d methods\n", methods)
// 反射调用Print方法
var params []reflect.Value
val.Elem().Method(0).Call(params)
}
func main() {
var a Student = Student{
Name: "stu01",
Age: 18,
Score: 92.8,
}
TestStruct(&a)
}
输出结果:
&{stu01 18 92.8} ptr
struct has 3 field
0 string
1 int
2 float32
struct has 3 methods
{stu01 18 92.8}
Elem反射获取tag
例子:
package main
import (
"fmt"
"reflect"
)
type Student struct {
Name string `json:"stu_name"`
Age int
Score float32
}
func TestStruct(a interface{}) {
typ := reflect.TypeOf(a)
tag := typ.Elem().Field(0).Tag.Get("json")
fmt.Printf("tag: %s\n", tag)
}
func main() {
var a Student = Student{
Name: "Musker",
Age: 22,
Score: 99.99,
}
TestStruct(&a)
}
输出结果:
tag: stu_name