golang反射包的使用

haitgo · · 4152 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

golang反射在某些特定的场景非常有用,比如我在web开发的时候,可以通过反射将表单映射到结构体上面,并能通过结构体定义的tag属性自动验证数据数据格式是否正确,如下例子:

我们可以将form表单

<form action="" method="POST">
    <input type="text" name="Name" />
    <input type="text" name="Age" />
</form>

映射到下面这个结构体里面去

type User struct{
      Name string `valid:"String"`
      Age int `valid:"Int"` 
}

 TypeOf 获取类型信息

ValueOf获取值信息

package main

import (
	"fmt"
	"reflect"
)

type a struct {
	Name string
	Age  string
}

func (this a) Test() {
	fmt.Println("test ok.")
}
func (this *a) Get() {
	fmt.Println("get ok.")
}
func (this *a) Print(id int, name string) {
	fmt.Println("id is ", id)
	fmt.Println("name is ", name)
}

func Test() {
	fmt.Println("func test is ok.")
}
func main() {
	d := &a{Name: "aaa", Age: "bbb"}
	v := reflect.ValueOf(d)
	ele := v.Elem()
	t := ele.Type()
	fmt.Println("\n读取对象的所有属性")
	for i := 0; i < t.NumField(); i++ {
		fmt.Println(t.Field(i).Name, ele.Field(i).Interface())
	}
	fmt.Println("\n读取对象的所有方法")
	for i := 0; i < t.NumMethod(); i++ {
		fmt.Println(t.Method(i).Name)
	}
	//反射调用方法
	fmt.Println("\n测试函数调用,看来还是e保险一些,不会出错")
	v.MethodByName("Get").Call(nil)
	v.MethodByName("Test").Call(nil)
	//使用ele.MethodByName("GET").Call(nil)会抛出异常
	//但是使用ele.MethodByName("Test").Call(nil)却是正常?因为Test没有用指针
	ele.MethodByName("Test").Call(nil)
	//调用有参数的反射
	fmt.Println("\n测试传值调用函数")
	vId := reflect.ValueOf(88)
	vName := reflect.ValueOf("小汪")
	v.MethodByName("Print").Call([]reflect.Value{vId, vName})

	fmt.Println("\n测试参数赋值,必须要用ele")
	ele.FieldByName("Name").SetString("哈哈")
	fmt.Println(d)

	c := 123
	tc := reflect.ValueOf(&c).Elem()
	tc.SetInt(333)
	fmt.Println(tc, reflect.TypeOf(&c).Elem().Name())
	fmt.Println(c)

}

 


有疑问加站长微信联系(非本文作者)

本文来自:开源中国博客

感谢作者:haitgo

查看原文:golang反射包的使用

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

4152 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传