這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
1、反射:可以在運行時動態擷取變數的相關資訊
Import(“reflect”)
兩個函數:
reflect.TypeOf()//擷取變數的類型,返回reflect.Type類型
reflect.ValueOf()//擷取變數的值,返回reflect.Value類型
reflect.Value.Kind()//擷取變數的類別,返回一個常量
reflect.Value.Interface()//轉換成interface{}類型
可逆狀態
樣本用法
package mainimport ( "fmt" "reflect")type Student struct { Name string Age int Score float32}func test(b interface{}) { t := reflect.TypeOf(b) fmt.Println(t) v := reflect.ValueOf(b) k := v.Kind() fmt.Println(k) iv := v.Interface() stu, ok := iv.(Student) if ok { fmt.Printf("%v %T\n", stu, stu) }}func testInt(b interface{}) { val := reflect.ValueOf(b) c := val.Int() fmt.Printf("get value interface{} %d\n", c)}func main() { var a Student = Student{ Name: "stu01", Age: 18, Score: 92, } test(a) testInt(1234)}
反射用法
package mainimport ( "fmt" "reflect")func main(){ var x float64=3.4 fmt.Println("type:",reflect.TypeOf(x)) v:=reflect.ValueOf(x) fmt.Println("value:",v) fmt.Println("type:",v.Type()) fmt.Println("kind:",v.Kind()) fmt.Println("value:",v.Float()) fmt.Println(v.Interface()) fmt.Printf("value is %5.2e\n",v.Interface()) y:=v.Interface().(float64) fmt.Println(y)}
反射練習
擷取變數的值
reflect.ValueOf(x).Float()reflect.ValueOf(x).Int()reflect.ValueOf(x).String()reflect.ValueOf(x).Bool()
反射之elem()修改指標的方法
package main//通過反射動態修改變數的值import ( "fmt" "reflect")type Student struct { Name string Age int Score float32}func test(b interface{}) { t := reflect.TypeOf(b) fmt.Println(t) v := reflect.ValueOf(b) k := v.Kind() fmt.Println(k) iv := v.Interface() stu, ok := iv.(Student) if ok { fmt.Printf("%v %T\n", stu, stu) }}func testInt(b interface{}) { val := reflect.ValueOf(b) val.Elem().SetInt(100) //val.Elem().Setint()相當於指標操作 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)}
val.Elem().SetInt()
用反射操作結構體
reflect.Value.NumField()擷取結構體中欄位的個數reflect.Value.Method(n).Call來條用結構體中的方法
反射取得結構體方法個數,欄位數
package main//通過反射動態修改變數的值import ( "fmt" "reflect")type Student struct { Name string 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 TestStruct(a interface{}) { val := reflect.ValueOf(a) kd := val.Kind() if kd != reflect.Struct { fmt.Println("expect struct") return } num := val.NumField() fmt.Printf("struct has %d fields\n", num) numOfMethod := val.NumMethod() fmt.Printf("struct has %d methods\n", numOfMethod)}func main() { var a Student a = Student{ Name: "stu01", Age: 18, Score: 92.8, } TestStruct(a) fmt.Println(a)}
代碼在這
反射練習
package main//通過反射動態修改變數的值import ( "fmt" "reflect")type NotKnownType struct { s1 string s2 string s3 string}//定義一個String方法func (n NotKnownType) String() string { return n.s1 + "-" + n.s2 + "-" + n.s3}var secret interface{} = NotKnownType{"Ada", "Go", "Oberon"}func main() { value := reflect.ValueOf(secret) //<main.NotKnownType Value> typ := reflect.TypeOf(secret) //main.NotKnownType fmt.Println(typ) knd := value.Kind() //struct fmt.Println(knd) for i := 0; i < value.NumField(); i++ { fmt.Printf("Field %d:%v\n", i, value.Field(i)) } results := value.Method(0).Call(nil) fmt.Println(results)//[Ada-Go-Oberon]}
反射練習
通過反射修改結構體
package mainimport ( "fmt" "reflect")type T struct { A int B string}func main() { t := T{23, "skidoo"} s := reflect.ValueOf(&t).Elem() typeOfT := s.Type() for i := 0; i < s.NumField(); i++ { f := s.Field(i) fmt.Printf("%d:%s %s=%v\n", i, typeOfT.Field(i).Name, f.Type(), f.Interface()) } s.Field(0).SetInt(77) s.Field(1).SetString("Sunset Strip") fmt.Println("t is now", t)}
反射修改結構體