Golang的学习笔记(14)--Go反射reflect
目录
Go中的反射reflect
reflectimport reflectreflect.Typereflect.Value
func TypeOf(i interface{}) Type
func ValueOf(i interface{}) Value
ValueValue.Type()TypeTypereflect.Valuereflect.TypeKind()reflect.Kindreflect.TypeKindTypetype zhengxing intvar i zhengxingTypezhengxingKindint
反射操作解析对象实例
下面列举一些通过反射操作来解析一些对象变量的实例:
- 简单数据类型
import (
"fmt"
"reflect"
)
func main(){
var i int = 1
v := reflect.ValueOf(i) //获取Value
fmt.Println(v.Int())
t := reflect.TypeOf(i) //获取Type
fmt.Println(t.Name())
}
intv.Int()intvValueValue.Float()Value.Bool()panict.Name()
- 结构体类型
import (
"fmt"
"reflect"
)
type dog struct {
name string
age int
}
func (d dog) Run(speed string) {
fmt.Println(d.name, "is running", speed)
}
func main(){
d := dog{ "dog", 2}
t := reflect.TypeOf(d)
fmt.Println("type: ", t.Name())
v := reflect.ValueOf(d)
fmt.Println("Fields:")
for i := 0; i < t.NumField(); i++ {
f := t.Field(i)
val := v.Field(i)
fmt.Println(f.Name, f.Type, val)
}
for i := 0; i < t.NumMethod(); i++ {
m := t.Method(i)
fmt.Println(m.Name, m.Type)
}
}
t := reflect.TypeOf(d)structv := reflect.ValueOf(d)t.NumField()f := t.Field(i)val := v.Field(i)t.NumMethod()tt.Method(i)
- 嵌套结构体
type User struct {
Id int
Name string
}
type Manager struct {
User
title string
}
func main(){
m := Manager{
User: User{1, "user"},
title: "kk",
}
t := reflect.TypeOf(m)
fmt.Println(t.Field(0)) //{User main.User 0 [0] true}
fmt.Println(t.Feile(1)) //{title main string 24 [1] false}
fmt.Println(t.FieldByIndex([]int{0, 0})) //{Id int 0 [0] false}
fmt.Println(t.FieldByIndex([]int{0, 1})) //{Name string 8 [1] false}
}
t.Field(0)t.Field(1)UsertitleUsertruefalseManagerUsert.FieldByIndex()intsliceManagerUser
通过反射来修改对象的值
- 简单数据类型
import "reflect"
func main(){
x := 123
v := reflect.ValueOf(x)
v.Elem().SetInt(999)
}
v.Elem()vSetInt()
- 结构体类型
type User struct {
Id int
Name string
}
func main(){
u := User{
Id: 1,
Name: "32",
}
Set(&u)
fmt.Println(u)
}
func Set(o interface{}) {
v := reflect.ValueOf(o)
if v.Kind() != reflect.Ptr{
fmt.Println("can not be set")
return
}
value := v.Elem()
if !value.CanSet(){
fmt.Println("can not be set")
}
f := value.FieldByName("Name")
if !f.IsValid() {
fmt.Println("can not be set")
return
}
if f.Kind() == reflect.String {
f.SetString("wangwang")
}
}
Set
panic: reflect: reflect.flag.mustBeAssignable using value obtained using unexported field
使用反射机制动态调用方法
使用反射机制可以在程序中动态调用方法
type dog struct {
Name string
Age int
}
func (d dog) Run(speed string) {
fmt.Println(d.name, "is running", speed)
}
func main(){
d := dog{"gogo", 1}
v := reflect.ValueOf(d)
mv := v.MethodByName("Run")
args := []reflect.Value{reflect.ValueOf("fastly")}
mv.Call(args)
}
MethodByName()Call()reflect.Valuereflect.ValueOf()relfect.Value