• Go


    Go 语言也有反射的机制,通过这种机制可以大大提高程序的灵活性。

    reflect包中的 TypeOf 与 ValueOf 方法

    首先,当我们想要使用反射技术的时候,我们需要先引用 reflect 包。

    import (
        "fmt"
        "reflect"
    )

    之后,我们就可以通过reflect包中的TypeOf方法来取到类型,并且使用ValueOf方法来获取字段及方法。我们来看一个实例

    // reflect.go
    package main
    
    import (
        "fmt"
        "reflect"
    )
    
    type User struct {
        Name string
        Age  int
        Sex  string
    }
    
    func (u User) SayHello() {
        fmt.Println("Hello there, I am %s ...", u.Name)
    }
    
    func main() {
        user := User{
            "Tony",
            30,
            "male"}
        info(user)
    }
    
    func info(o interface{}) {
        t := reflect.TypeOf(o)
        fmt.Printf("Type is: %s 
    ", t.Name())
    
        fmt.Printf("Fields are: 
    ")
    
        // find out fileds
        v := reflect.ValueOf(o)
    
        for i := 0; i < t.NumField(); i++ {
            f := t.Field(i)
            val := v.Field(i).Interface()
            fmt.Printf("%6s: %v=%v
    ", f.Name, f.Type, val)
        }
    
        // find out methods
        for i := 0; i < t.NumMethod(); i++ {
            m := t.Method(i)
            fmt.Printf("%6s: %v
    ", m.Name, m.Type)
        }
    }

    output:

     使用反射修改类型

    如果我们需要通过反射的方式来修改类型的字段,那么传入给ValueOf()方法的参数应该是对象的引用。

    // reflect1.go
    package main
    
    import (
        "fmt"
        "reflect"
    )
    
    type People struct {
        Name string
        Age  int
    }
    
    func main() {
        p := People{"Tony", 30}
        fmt.Printf("my name is: %s
    ", p.Name)
    
        val := reflect.ValueOf(&p)
        f := val.Elem().FieldByName("Name")
        f.SetString("Tom")
    
        fmt.Printf("my name is: %s
    ", p.Name)
    }

    使用反射来“动态”调用方法

    // reflect1.go
    package main
    
    import (
        "fmt"
        "reflect"
    )
    
    type People struct {
        Name string
        Age  int
    }
    
    func (p People) Hello(name string) {
        fmt.Printf("Hello there, I am %s", name)
    }
    
    func main() {
        p := People{"Tony", 30}
        v := reflect.ValueOf(p)
        mv := v.MethodByName("Hello")
    
        args := []reflect.Value{reflect.ValueOf("Tom")}
        mv.Call(args)
    }

    需要注意的是,通过反射调用方法的时候需要以slice的形式传入参数,

     args := []reflect.Value{reflect.ValueOf("Tom")}

     最后使用method.call来调用方法
    mv.Call(args)
  • 相关阅读:
    前端笔记(关于解决打包时报node-sass错误的问题)
    前端笔记(Echarts学习总结)
    前端笔记(近期整理的一些开发备注)
    代码(css3向下箭头指引)
    Hexo 博客利用 Nginx 实现中英文切换
    prefetch 和 preload 及 webpack 的相关处理
    利用 Github 网络钩子实现自动化部署
    使用 Nginx 实现 301 跳转至 https 的根域名
    作为 attribute 和 property 的 value 及 Vue.js 的相关处理
    使用 Vue.js 改写 React 的官方教程井字棋
  • 原文地址:https://www.cnblogs.com/atuotuo/p/7055049.html
Copyright © 2020-2023  润新知