這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
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 mainimport ("fmt""reflect")type a struct {Name stringAge 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 := 123tc := reflect.ValueOf(&c).Elem()tc.SetInt(333)fmt.Println(tc, reflect.TypeOf(&c).Elem().Name())fmt.Println(c)}