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)
}
有疑问加站长微信联系(非本文作者)