GO開發[六]:golang反射(reflect)
阿新 • • 發佈:2018-02-08
回調 set var tin 一個 相關信息 運行 odi 設置
反射
反射:可以在運行時動態獲取變量的相關信息
? Import (“reflect”)
reflect.TypeOf,獲取變量的類型,返回reflect.Type類型
reflect.ValueOf,獲取變量的值,返回reflect.Value類型
reflect.Value.Kind,獲取變量的類別,返回一個常量
reflect.Value.Interface(),轉換成interface{}類型
reflect.ValueOf(x).Float()
reflect.ValueOf(x).Int()
reflect.ValueOf(x).String()
reflect.ValueOf(x).Bool()
通過反射的來改變變量的值
reflect.Value.SetXX相關方法,比如:
reflect.Value.SetFloat(),設置浮點數
reflect.Value.SetInt(),設置整數
reflect.Value.SetString(),設置字符串
package main import ( "fmt" "reflect" ) type Student struct { Name string Age int Score float32 } func test(b interface{}) { //t是b的一個拷貝,修改t,b不會修改!t := reflect.TypeOf(b) //獲取變量的類型,返回reflect.Type類型 fmt.Println(t) v := reflect.ValueOf(b) //獲取變量的值,返回reflect.Value類型 fmt.Println(v) k := v.Kind() //獲取變量的類別,返回一個常量 fmt.Println(k) iv := v.Interface() stu, ok := iv.(Student) if ok { fmt.Printf("%v %T\n", stu, stu) } } func testInt(binterface{}) { val := reflect.ValueOf(b) fmt.Println(val.Elem()) val.Elem().SetInt(100) //val.Elem()用來獲取指針指向的變量,相當於: //var a *int; //*a = 100 c := val.Elem().Int() fmt.Printf("get value interface{} %d\n", c) fmt.Printf("string val:%d\n", val.Elem().Int()) } func main() { var a Student = Student{ Name: "stu01", Age: 18, Score: 92, } test(a) var b int = 1 b = 200 testInt(&b) fmt.Println(b) }
reflect.Value.NumField()獲取結構體中字段的個數
reflect.Value.Method(n).Call來調用結構體中的方法
package main import ( "fmt" "reflect" ) type NotknownType struct { s1 string s2 string s3 string } func (n NotknownType) String() string { return n.s1 + "-" + n.s2 + "-" + n.s3 } var secret interface{} = NotknownType{"greg", "learn", "go"} func main() { value := reflect.ValueOf(secret) // <main.NotknownType Value> typ := reflect.TypeOf(secret) // main.NotknownType fmt.Println(value,typ) knd := value.Kind() // struct fmt.Println(knd) for i := 0; i < value.NumField(); i++ { //value.Field(i).SetString("ningxin") fmt.Printf("Field %d: %v\n", i, value.Field(i)) } results := value.Method(0).Call(nil) fmt.Printf("%T\n",results) fmt.Println(results) }
反射回調函數和方法
package main import ( "fmt" "reflect" ) type Student struct { Name string Age int Score float64 Sex string } func (s Student) Print() { fmt.Println("---start----") fmt.Println(s) fmt.Println("---end----") } func (s Student) Set(name string, age int, score float64, sex string) { s.Name = name s.Age = age s.Score = score s.Sex = sex fmt.Println(s) } func TestStruct(a interface{}) { val := reflect.ValueOf(a) kd := val.Kind() if kd != reflect.Ptr && val.Elem().Kind() == reflect.Struct { fmt.Println("expect struct") return } num := val.Elem().NumField() val.Elem().Field(0).SetString("greg") for i := 0; i < num; i++ { fmt.Printf("%d %v\n", i, val.Elem().Field(i).Kind()) } fmt.Printf("struct has %d fields\n", num) numOfMethod := val.Elem().NumMethod() fmt.Printf("struct has %d methods\n", numOfMethod) val.Elem().Method(0).Call(nil) params := make([]reflect.Value,4) params[0]=reflect.ValueOf("hhhhhhhhh") params[1]=reflect.ValueOf(188888888) params[2]=reflect.ValueOf(59.99999) params[3]=reflect.ValueOf("male") //fmt.Println(params) val.Elem().Method(1).Call(params) } func main() { var a Student = Student{ Name: "ningxin", Age: 18, Score: 92.8, } fmt.Println(a) TestStruct(&a) }
json序列化是通過反射實現的
package main import ( "encoding/json" "fmt" "reflect" ) type Student struct { Name string `json:"student_name"` Age int Score float32 Sex string } func (s Student) Set(name string, age int, score float32, sex string) { s.Name = name s.Age = age s.Score = score s.Sex = sex } func Tagtest(a interface{}) { tye := reflect.TypeOf(a) fmt.Println("///////////",tye) fmt.Println(tye.Elem()) fmt.Println(tye.Elem().Field(0)) fmt.Println(tye.Elem().Field(0).Tag) tag := tye.Elem().Field(0).Tag.Get("json") fmt.Printf("tag=%s///////////\n", tag) } func main() { var a Student = Student{ Name: "stu01", Age: 18, Score: 92.8, } result, _ := json.Marshal(a) fmt.Println("json result:", string(result)) Tagtest(&a) fmt.Println(a) }
GO開發[六]:golang反射(reflect)