zoukankan      html  css  js  c++  java
  • golang之reflect

    reflect,反射。

    利用reflect,可以得到一个struct的相关信息。

    package main
    
    import (
    	"fmt"
    	"reflect"
    )
    
    type User struct {
    	Id int
    	Name string
    	Age int
    }
    
    func (u User) Hello(name string) {
    	fmt.Printf("hello %s, my name is %s
    ", name, u.Name)
    }
    
    type Manager struct {
    	User
    	title string
    }
    
    func main() {
    	// modify variable through reflect
    	//x := 123
    	//v := reflect.ValueOf(&x)
    	//v.Elem().SetInt(234)
    	//fmt.Println(x)
    
    	u := User{1, "xiaoming", 12}
    	u.Hello("atom")
    
    	// call method through reflect
    	v := reflect.ValueOf(u)
    	mv := v.MethodByName("Hello")
    	args := []reflect.Value{reflect.ValueOf("jack")}
    	mv.Call(args)
    
    	Info(u)
    	Set(&u)
    	Info(u)
    
    	m := Manager{User{1, "xiaoming", 12}, "rd"}
    	// get nested struct field
    	t := reflect.TypeOf(m)
    	fmt.Printf("%#v
    ", t.Field(0))
    	fmt.Printf("%#v
    ", t.FieldByIndex([]int{0,0}))
    }
    
    func Info(i interface{}) {
    	t := reflect.TypeOf(i)
    
    	if t.Kind() != reflect.Struct {
    		fmt.Println("Type Error")
    		return
    	}
    	fmt.Println("Type:", t.Name())
    
    	v := reflect.ValueOf(i)
    
    	// get fields
    	fmt.Println("Fields:")
    	for i := 0; i < t.NumField(); i++ {
    		f := t.Field(i)
    		val := v.Field(i).Interface()
    		fmt.Printf("%6s: %v = %v
    ", f.Name, f.Type, val)
    	}
    	// get methods
    	fmt.Println("Methods:")
    	for i := 0; i < t.NumMethod(); i++ {
    		m := t.Method(i)
    		fmt.Printf("%6s: %v
    ", m.Name, m.Type)
    	}
    }
    
    func Set(i interface{}) {
    	v := reflect.ValueOf(i)
    	if v.Kind() != reflect.Ptr || !v.Elem().CanSet() {
    		fmt.Println("Error")
    		return
    	} else {
    		v = v.Elem()
    	}
    
    	f := v.FieldByName("Name")
    	if !f.IsValid() {
    		fmt.Println("Bad Field")
    	}
    	if f.Kind() == reflect.String {
    		f.SetString("byebye")
    	}
    }

    输出如下:

    hello atom, my name is xiaoming
    hello jack, my name is xiaoming


    Type: User
    Fields:
    Id: int = 1
    Name: string = xiaoming
    Age: int = 12
    Methods:
    Hello: func(main.User, string)


    Type: User
    Fields:
    Id: int = 1
    Name: string = byebye
    Age: int = 12
    Methods:
    Hello: func(main.User, string)


    reflect.StructField{Name:"User", PkgPath:"", Type:(*reflect.rtype)(0x10d9e00), Tag:"", Offset:0x0, Index:[]int{0}, Anonymous:true}
    reflect.StructField{Name:"Id", PkgPath:"", Type:(*reflect.rtype)(0x10c4e60), Tag:"", Offset:0x0, Index:[]int{0}, Anonymous:false}

    需要注意的一个地方是:

    结构体的field首字母需要大写,否则会报错"panic: reflect.Value.Interface: cannot return value obtained from unexported field or method"

    参考资料

    Go编程基础

  • 相关阅读:
    IntelliJ IDEA创建Java项目
    Oracle常见五个服务的作用
    Windows2008开启telnet客户端命令
    整理jQuery操作select控件常用功能代码
    Asp.Net程序报错
    Oracle中start with connect by prior用法
    Spring中无法访问resources目录下页面或静态资源
    对搜狗输入法的个人评价
    课堂练习寻找水王
    典型用户分析及用户场景分析
  • 原文地址:https://www.cnblogs.com/gattaca/p/8569596.html
Copyright © 2011-2022 走看看