IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    golang标准库reflect包实现操作任意类型对象

    mckee发表于 2015-11-03 13:24:40
    love 0

    空接口interface{},reflect配合空接口,让原本是静态类型的go具备了很多动态类型语言的特征。

    • func TypeOf(i interface{}) Type

    TypeOf返回接口中保存的值的类型,TypeOf(nil)会返回nil。

    • func ValueOf(i interface{}) Value

    ValueOf返回一个初始化为i接口保管的具体值的Value,ValueOf(nil)返回Value零值。

    • func (v Value) NumField() int

    返回v持有的结构体类型值的字段数,如果v的Kind不是Struct会panic
     

    利用reflect反射出所有struct字段和方法:
    package main
    
    import (
    	"fmt"
    	"reflect"
    )
    
    type User struct {
    	Name string
    	Age  int
    	Id   string
    }
    
    func (u User)sayHello() {
    	fmt.Println("hello!")
    }
    
    func main() {
    	u := User{Name:"mckee", Age:20, Id:"user100"};
    
    	t := reflect.TypeOf(u)
    	fmt.Println(t) //main.User
    	fmt.Println(t.Name()) //User
    	fmt.Println(t.NumField()) //3
    	fmt.Println(t.Kind()) //struct
    
    	//检测类型
    	if k := t.Kind(); k != reflect.Struct {
    		return
    	}
    
    	//输出所有的属性,结果如下:
    	/*
    	Name string mckee
    	Age int 20
    	Id string user100
    	 */
    	v := reflect.ValueOf(u)
    	for i := 0; i < t.NumField(); i++  {
    		fieldType := t.Field(i)
    		fmt.Println(fieldType.Name, fieldType.Type, v.Field(i).Interface())
    	}
    
    	//输出所有方法
    	for i := 0; i < t.NumMethod(); i++ {
    		m := t.Method(i)
    		fmt.Println(m.Name, m.Type) //sayHello func(main.User)
    	}
    }

    利用reflect动态调用方法:

    package main
    
    import (
    	"fmt"
    	"reflect"
    )
    
    type User struct {
    	Name string
    	Age  int
    	Id   string
    }
    
    func (u User)SayHello(name string) {
    	fmt.Println("hello, ", name, "! my name is ", u.Name)
    }
    
    func main() {
    	u := User{Name:"mckee", Age:20, Id:"user100"};
    	
    	//hello,  Jack ! my name is  mckee
    	reflect.ValueOf(u).MethodByName("SayHello").Call([]reflect.Value{reflect.ValueOf("Jack")})
    }



沪ICP备19023445号-2号
友情链接