zoukankan      html  css  js  c++  java
  • GO开发[六]:golang反射(reflect)

    反射

    反射:可以在运行时动态获取变量的相关信息

    ​ 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
    ", 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
    ", c)
       fmt.Printf("string val:%d
    ", 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
    ", i, value.Field(i))
        }
    
        results := value.Method(0).Call(nil)
        fmt.Printf("%T
    ",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
    ", i, val.Elem().Field(i).Kind())
       }
    
       fmt.Printf("struct has %d fields
    ", num)
       numOfMethod := val.Elem().NumMethod()
       fmt.Printf("struct has %d methods
    ", 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///////////
    ", 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)
    }
  • 相关阅读:
    linux如何添加内核模块
    LINUX内核符号表
    MIPS 架构
    将char转成bit,文件读写
    回顾一下今天VIM历程,加深印象,以免忘记!
    Notebook of A Road Map Through Nachos
    老林课上笔记
    C# 通过探测邮件服务器进行Email地址有效性检验
    详解在visual studio中使用git版本系统(图文)
    基于aspnet Forms身份验证基本原理
  • 原文地址:https://www.cnblogs.com/ningxin18/p/8430167.html
Copyright © 2011-2022 走看看