zoukankan      html  css  js  c++  java
  • 9.1 Go 反射

    9.1 Go 反射

    反射:可以在运行时,动态获取变量的信息,比如变量的类型,类别

    1.对于结构体变量,还可以获取到结构体的字段,方法

    2.实现这个功能的是 reflect包

    reflect.TypeOf(),获取变量的类型,返回reflect.Type类型 
    reflect.ValueOf(),获取变量的值,返回reflect.Value类型 
    reflect.Value.Kind(),获取变量的类别,返回一个常量 
    reflect.Value.Interface(),转换成interface{}类型
    

    使用反射场景,json序列化

    package main
    
    import (
        "encoding/json"
        "fmt"
    )
    
    type Student struct {
        Name  string `json:"学生名"`
        Age   int    `json:"学生年纪"`
        Class string `json:"班级"`
    }
    
    func main() {
        stu := Student{
            "尼古拉斯赵四",
            18,
            "舞王班",
        }
        data, err := json.Marshal(stu)
        if err != nil {
            fmt.Println("序列化出错", err)
        }
        fmt.Println("json序列化结果:", string(data))
    }
    

    反射获取基本类型

    package main
    
    import (
        "fmt"
        "reflect"
    )
    
    func main() {
        var num int64 = 12345
        fmt.Println("num类型", reflect.TypeOf(num))
        //获取变量的值
        resNum := reflect.ValueOf(num)
        fmt.Printf("类型:%T  值:%v
    ", resNum, resNum)
        fmt.Printf("resNum值:%v
    ", resNum)
        fmt.Printf("resNum类型:%v
    ", resNum.Type())
        fmt.Printf("resNum种类:%v
    ", resNum.Kind())
        fmt.Printf("resNum确认值:%v
    ", resNum.Int())
    }
    

    反射获取结构体

    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)
        fmt.Println("参数值:", v)
    
        k := v.Kind()
        fmt.Println("参数种类:", k)
        //转化为接口返回
        iv := v.Interface()
        fmt.Printf("类型:%T 值:%v
    ", iv, iv)
        //类型断言,如果这个接口是student类型
        stu, ok := iv.(Student)
        if ok {
            fmt.Printf("结构体值:%v 类型:%T
    ", stu, stu)
        }
    }
    
    func main() {
        var a Student = Student{
            Name:  "周星驰",
            Age:   18,
            Score: 99,
        }
        //传入结构体
        test(a)
    }
    

    反射elem获取指针指向的变量

    package main
    
    import (
        "fmt"
        "reflect"
    )
    
    //fv.Elem()用来获取指针指向的变量
    func testInt(b interface{}) {
        //获取b的类型
        val := reflect.ValueOf(b)
        fmt.Printf("参数b的类型是:%T 值是:%v
    ", val, val)
        fmt.Printf("val.Elem()获取到变量的类型:%T 值:%v
    ", val.Elem(), val.Elem())
        //修改val的值
        val.Elem().SetInt(100)
        //返回 一个int值类型
        c := val.Elem().Int()
        fmt.Printf("类型:%T 值是:%d
    ", c, c)
    }
    
    func main() {
        var b int = 1
        b = 200
        testInt(&b)
        fmt.Println("b的值:", b)
    }
    

    理解reflect.Value.Elem()

    package main
    
    import (
        "fmt"
        "reflect"
    )
    
    func main() {
        var num int = 100
        //返回变量的值,传入地址,那就是内存地址的值
        fn := reflect.ValueOf(&num)
        //修改指针指向的值,也就是修改num的值
        fn.Elem().SetInt(222)
        fmt.Printf("此时num的值:%d
    ", num)
    
        //以上操作,等同于
        var num2 = 111
        var b *int = &num2
        *b = 333
        fmt.Printf("b的类型:%T
    ", b)
        fmt.Println(num2)
    }
  • 相关阅读:
    opacity兼容性以及存在问题处理
    删除节点方法要注意的区别
    java基础-常见面试题(一)
    第04次作业-树
    第03次作业-栈和队列
    第02次作业-线性表
    Data_Structure-绪论作业
    C语言第二次实验报告
    C语言第一实验报告
    mysql 查询优化
  • 原文地址:https://www.cnblogs.com/open-yang/p/11256910.html
Copyright © 2011-2022 走看看