一、反射获取类型对象与值
package main
import (
"fmt"
"reflect"
)
func main() {
a := 36
atype := reflect.TypeOf(a)
fmt.Println(atype.Name()) //获取类型名称为int
avalue := reflect.ValueOf(a)
fmt.Println(avalue.Int()) //获取具体的数值
}
二、反射获取结构体类型名称与类型
package main
import (
"fmt"
"reflect"
)
type myobject struct {
Name string
Sex int
Age int `json:"age"`
}
func main() {
typeof := reflect.TypeOf(myobject{})
fmt.Println(typeof.Name()) //获取反射类型对象 myobject
fmt.Println(typeof.Kind()) //获取反射类型种类 myobject
}
三、反射获取指针名称和类型
package main
import (
"fmt"
"reflect"
)
type myobject struct {
Name string
Sex int
Age int `json:"age"`
}
func main() {
typeof := reflect.TypeOf(&myobject{})
fmt.Println(typeof.Elem().Name()) //获取指针类型指向的元素类型的名称
fmt.Println(typeof.Elem().Kind()) //获取指针类型指向的元素类型的种类
}
四、反射获取结构体成员的类型
package main
import (
"fmt"
"reflect"
)
type myobject struct {
Name string
Sex int
Age int `json:"age"`
}
func main() {
typeof := reflect.TypeOf(myobject{})
fieldnum := typeof.NumField() //获取结构体成员字段的数量
for i := 0; i < fieldnum; i++ {
fieldname := typeof.Field(i) //索引对应的字段信息
fmt.Println(fieldname)
name, err := typeofmystruct.FieldByName("Name")//根据指定的字符串返回对应的字段信息
fmt.Println(name, err)
}
}
五、反射值对象获取任意值
package main
import (
"fmt"
"reflect"
)
func main() {
a := 2020
valof := reflect.ValueOf(a) //先通过reflect.ValueOf 获取反射的值对象
fmt.Println(valof)
//再通过值对象通过类型断言转换为指定类型
fmt.Println(valof.Interface()) //转换为interface{} 类型
fmt.Println(valof.Int()) //将值以int类型返回
}
注意:.Interface() 将值以interface{}任意类型返回。还有各自对应的类型, .Int()、.Uint() 、.Floact() 、.Bool() 、.Bytes() 、.String()。
六、反射获取结构体的成员字段的值
package main
import (
"fmt"
"reflect"
)
type myobject struct {
Name string
Age int
}
func main() {
h := myobject{"测试", 20}
fmt.Println(h)
hofvalue := reflect.ValueOf(h) //获取结构体的reflect.Value对象。
for i := 0; i < hofvalue.NumField(); i++ { //循环结构体内字段的数量
//获取结构体内索引为i的字段值
fmt.Println(hofvalue.Field(i).Interface())
}
fmt.Println(hofvalue.Field(1).Type()) //获取结构体内索引为1的字段的类型
}
七、反射对象的空值处理
package main
import (
"fmt"
"reflect"
)
func main() {
var a *int //声明一个变量a为nil的空指针
fmt.Println(reflect.ValueOf(a).IsNil()) //判断是否为nil 返回true
//当reflect.Value不包含任何信息,值为nil的时候IsValid()就返回false
fmt.Println(reflect.ValueOf(nil).IsValid())
}
八、反射值对象修改变量的值
package main
import (
"fmt"
"reflect"
)
func main() {
//声明变量a
a := 100
fmt.Printf("a的内存地址为:%p\n", &a)
//获取变量a的反射类型reflect.Value 的地址
rf := reflect.ValueOf(&a)
fmt.Println("通过反射获取变量a的地址:", rf)
//获取a的地址的值
rval := rf.Elem()
fmt.Println("反射a的值:", rval)
//修改a的值
rval.SetInt(200)
fmt.Println("修改之后反射类型的值为:", rval.Int())
//原始值也被修改
fmt.Println("原始a的值也被修改为:", a)
}
注意
:
SetInt(x) 设置值为x, 类型必须是int类型。
SetUint(x) 设置值为x, 类型必须是uint类型。
SetFloat(x) 设置值为x, 类型必须是float32或者float64类型。
SetBool(x) 设置值为x, 类型必须是bool类型。
SetBytes(x) 设置值为x, 类型必须是[]Byte类型。
SetString(x) 设置值为x, 类型必须是string类型。
九、反射调用函数方法
package main
import (
"fmt"
"reflect"
)
func myfunc(a, b int) int {
return a + b
}
func main() {
r_func := reflect.ValueOf(myfunc)
//设置函数需要传入的参数也必须是反射类型
params := []reflect.Value{reflect.ValueOf(10), reflect.ValueOf(20)}
//反射调用函数
res := r_func.Call(params)
//获取返回值
fmt.Println(res[0].Int())
}