一聚教程网:一个值得你收藏的教程网站

热门教程

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

时间:2022-06-25 04:44:26 编辑:袖梨 来源:一聚教程网

空接口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")})
}

热门栏目