所謂反射(reflect)就是能檢查程序在運行時的狀態。this
使用反射的三條定律:spa
使用reflect通常分紅三步:code
一、要去反射是一個類型的值(這些值都實現了空接口),首先須要把它轉化成reflect對象(reflect.Type 或 reflect.Value):對象
func TypeOf(i iterface{}) Type // 返回接口中保存的值的類型,TypeOf(nil)會返回nil。
func ValueOf(i iterface{}) Value // 返回一個初始化爲i接口保管的具體值的Value,ValueOf(nil)返回Value零值。
二、將reflect對象轉化成相應的值,例如:blog
tag := t.Elem().Field(0).Tag // 獲取定義在struct裏面的標籤 name := v.Elem().Field(0).String() // 獲取存儲在第一個字段裏面的值
三、獲取反射值能返回相應的類型和數值接口
var x float64 = 3.4
v := reflect.ValueOf(x) fmt.Println("type:", v.Type()) fmt.Println("kind is float64:", v.Kind() == reflect.Float64) fmt.Println("value:", v.Float())
最後,反射的話,那麼反射的字段必須是可修改的。反射的字段必須是可讀寫的意思是,若是下面這樣寫,那麼會發生錯誤string
var x float64 = 3.4
v := reflect.ValueOf(x) v.SetFloat(7.1)
若是要修改相應的值,必須這樣寫it
var x float64 = 3.4
p := reflect.ValueOf(&x) v := p.Elem() v.SetFloat(7.1)
先看一個例子,如何獲取struct tag:class
type User struct { Name string `user_name` Age int `age` } func (this *User) AddAge() { this.Age += 1 } func main() { user := &User{"John", 18} t := reflect.TypeOf(user) s := t.Elem() for i := 0; i < s.NumField(); i++ { fmt.Println(s.Field(i).Tag) } }