1. 程式人生 > >GO開發[六]:golang反射(reflect)

GO開發[六]:golang反射(reflect)

回調 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(b
interface{}) { 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)