這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
reflect反射,可以通過reflect反射結構體所包含的屬性和方法,然後進行一些賦值和方法的調用,靈活度比較高
package myimport ( ft "fmt" "reflect")type User struct { Id int Name string}func (user User) Print() { ft.Println("reflect Print()")}func Reflect(inter interface{}) { t := reflect.TypeOf(inter) //從介面中擷取結構的類型 if k:=t.Kind();k!=reflect.Struct{//判斷傳入的是否是struce類型,而不是指標類型*User,指標類型報錯 ft.Println("type is not true") return } ft.Println("類型名稱:", t.Name()) v := reflect.ValueOf(inter) //從介面中擷取結構的值 for i := 0; i < t.NumField(); i++ { //遍曆所包含的屬性欄位 f := t.Field(i) //擷取到欄位 val := v.Field(i).Interface() ft.Println("欄位簽名:", f.Type, " 欄位名稱:", f.Name, " 值:", val) } for i := 0; i < t.NumMethod(); i++ { //遍曆所綁定的方法 m := t.Method(i) //擷取到方法 ft.Println("方法名稱:", m.Name, " 方法簽名:", m.Type) }}
package myimport ( ft "fmt" "reflect")type User struct { Id int Name string Info}type Info struct { Age int}func (user User) Print(name string) { ft.Println("reflect Print()",name)}func Reflect(inter interface{}) { t := reflect.TypeOf(inter) //從介面中擷取結構的類型 v := reflect.ValueOf(inter) //從介面中擷取結構的值 if t.Kind() == reflect.Ptr && v.Elem().CanSet() { //傳入的是指標,可以修改 v = v.Elem() if f := v.Kind(); f == reflect.Struct {//如果欄位屬性是結構體 if x := v.FieldByName("Age"); x.IsValid() { x.SetInt(888) } } if f := v.FieldByName("Name"); f.Kind() == reflect.String && f.IsValid() { f.SetString("haha") } if f := v.FieldByName("Id"); f.Kind() == reflect.Int && f.IsValid() { f.SetInt(99) } if f := v.MethodByName("Print"); f.IsValid() { args := []reflect.Value{reflect.ValueOf("測試")} f.Call(args) } }}
package mainimport ( f "fmt" "com.guo/mytest/something")func main(){ r:=something.User{1,"haha",something.Info{100,"廣州市"}} something.Reflect(&r) something.Reflect(r) f.Println("修改後結果:",r)}