反射的知识点比较晦涩,后期会对此知识点展开深入的分析及示例代码展示

  • 反射可达大提高程序的灵活性,使得inferface{}有更大的发挥余地

  • 反射使用TypeOf和ValueOf函数从接口中获取目标对象信息:字段属性,方法信息

    1. package main
    2. import (
    3. "fmt"
    4. "reflect"
    5. )
    6. type User struct { //定义一个结构类型
    7. Id int
    8. Name string
    9. Age int
    10. }
    11. func (u User) Hello() { //定义一个结构方法
    12. fmt.Println("Hello world")
    13. }
    14. func Info(o interface{}) { //定义一个方法,参数为空接口
    15. t := reflect.TypeOf(o) //获取接收到的接口类型
    16. fmt.Println("Type:", t.Name()) //获取名称
    17. v := reflect.ValueOf(o) //获取接口的字段
    18. fmt.Println("Fields:")
    19. //获取结构字段
    20. for i := 0; i < t.NumField(); i++ { //for循环,取出所拥有的字段
    21. f := t.Field(i) //获取值字段
    22. val := v.Field(i).Interface() //获取字段的值
    23. fmt.Printf("%6s:%v=%v\n", f.Name, f.Type, val)
    24. }
    25. //通过接口获取结构的方法
    26. for i := 0; i < t.NumMethod(); i++ {
    27. m := t.Method(i)
    28. fmt.Printf("%6s:%v\n", m.Name, m.Type)
    29. }
    30. }
    31. func main() {
    32. u := User{1, "OK", 12} //实例化一个结构
    33. Info(u) //调用Info函数
    34. }
    35. /*输出
    36. Type: User
    37. Fields:
    38. Id:int=1
    39. Name:string=OK
    40. Age:int=12
    41. Hello:func(main.User)
    42. */
  • 反射会将匿名字段作为独立字段(匿名字段本质)

    1. package main
    2. import (
    3. "fmt"
    4. "reflect"
    5. )
    6. type User struct { //定义一个结构类型
    7. Id int
    8. Name string
    9. Age int
    10. }
    11. type Manager struct {
    12. User //嵌入User结构,User就是Manager结构的匿名字段
    13. title string
    14. }
    15. func main() {
    16. m := Manager{User: User{1, "mm", 27}, title: "name"} //注意初始化方式
    17. t := reflect.TypeOf(m) //传递结构
    18. fmt.Printf("%#v\n", t.Field(0)) //获取索引为0的字段信息,即User字段信息
    19. fmt.Printf("%#v\n", t.FieldByIndex([]int{0, 0})) //根据索引取出ID的字段信息()
    20. } //{0,0}--User在Manager索引为0,ID在User索引为0
    21. /*output
    22. reflect.StructField{Name:"User", PkgPath:"", Type:(*reflect.rtype)(0x4ac220), Tag:"",
    23. Offset:0x0, Index:[]int{0}, Anonymous:true}
    24. "Anonymous:true" 其中包含Anonymous(匿名)字段
    25. */
  • 想要利用反射修改对象状态,前提是interface.data是settable,即pointer-interface(指针接口)

    • 示例1
    1. //这是一个简单的修改对象状态
    2. package main
    3. import (
    4. "fmt"
    5. "reflect"
    6. )
    7. func main() {
    8. x := 123 //底层类型是int类型
    9. v := reflect.ValueOf(&x) //传递x的指针
    10. v.Elem().SetInt(999) //通过方法修改x变量的值
    11. fmt.Println(x)
    12. }
    13. /*输出
    14. x---> 999
    15. */
    • 示例2
    1. //通过反射修改结构字段
    2. package main
    3. import (
    4. "fmt"
    5. "reflect"
    6. )
    7. type User struct {
    8. Name string
    9. ID int
    10. Age int
    11. }
    12. func main() {
    13. u := User{"MAOZI", 1, 22}
    14. Set(&u)
    15. fmt.Println(u)
    16. }
    17. func Set(o interface{}) {
    18. v := reflect.ValueOf(o)
    19. if v.Kind() != reflect.Ptr && !v.Elem().CanSet() { //判断是否为反射typestring,且可以被修改
    20. fmt.Println("fuck")
    21. return
    22. } else { //如果条件都满足
    23. v = v.Elem()
    24. }
    25. f := v.FieldByName("Name") //通过名字段名找字段
    26. if !f.IsValid() { //IsValid方法判断是否找了字段
    27. fmt.Println("invalid")
    28. return
    29. }
    30. if f.Kind() == reflect.String {
    31. f.SetString("momo")
    32. }
    33. }
    34. /*输出
    35. {momo 1 22}
    36. */
  • 通过反射可以"动态"调用方法

    1. //通过反射动态调用结构方法
    2. package main
    3. import (
    4. "fmt"
    5. "reflect"
    6. )
    7. type User struct {
    8. Name string
    9. ID int
    10. Age int
    11. }
    12. func (u User) Hello(name string) {
    13. fmt.Println("Hello", name, ",my name is", u.Name)
    14. }
    15. func main() {
    16. u := User{"Golang", 1, 22}
    17. v := reflect.ValueOf(u)
    18. mv := v.MethodByName("Hello") //反射:通过名字找结构字段信息
    19. args := []reflect.Value{reflect.ValueOf("Python")}
    20. mv.Call(args)
    21. }
    22. /*输出
    23. Hello Python ,my name is Golang
    24. */

golang基础--reflect反射的更多相关文章

  1. golang:reflect反射

    因为之前一直以C++为主要开发语言,所以刚接触go语言中的reflect时感觉很懵逼,因此决定找资料彻底学习一下. 到底反射是什么? https://blog.golang.org/laws-of-r ...

  2. golang 使用reflect反射结构体

    "反射结构体"是指在程序执行时,遍历结构体中的字段以及方法. 1.反射结构体 下面使用一个简单的例子说明如何反射结构体. 定义一个结构体,包括3个字段,以及一个方法. 通过refl ...

  3. golang 通过reflect反射修改值

    不是所有的反射值都可以修改.对于一个反射值是否可以修改,可以通过CanSet()进行检查. 要修改值,必须满足: 可以寻址 可寻址的类型: 指针指向的具体元素 slice的元素 可寻址的结构体的字段( ...

  4. golang中的反射reflect详解

    先重复一遍反射三定律: 1.反射可以将"接口类型变量"转换为"反射类型对象". 2.反射可以将"反射类型对象"转换为"接口类型变量 ...

  5. Go语言基础之反射

    Go语言基础之反射 本文介绍了Go语言反射的意义和基本使用. 变量的内在机制 Go语言中的变量是分为两部分的: 类型信息:预先定义好的元信息. 值信息:程序运行过程中可动态变化的. 反射介绍 反射是指 ...

  6. Golang 接口与反射知识要点

    目录 Golang 接口与反射知识要点 1. 接口类型变量 2. 类型断言 3. 鸭子类型 4. 反射机制 5. reflect 包 TypeOf().ValueOf() Type().Kind() ...

  7. GO学习-(17) Go语言基础之反射

    Go语言基础之反射 本文介绍了Go语言反射的意义和基本使用. 变量的内在机制 Go语言中的变量是分为两部分的: 类型信息:预先定义好的元信息. 值信息:程序运行过程中可动态变化的. 反射介绍 反射是指 ...

  8. Golang 基础之基础语法梳理 (三)

    大家好,今天将梳理出的 Go语言基础语法内容,分享给大家. 请多多指教,谢谢. 本次<Go语言基础语法内容>共分为三个章节,本文为第三章节 Golang 基础之基础语法梳理 (一) Gol ...

  9. 黑马程序员:Java基础总结----反射

    黑马程序员:Java基础总结 反射   ASP.Net+Android+IO开发 . .Net培训 .期待与您交流! 反射 反射的基石:Class类 Class类代表Java类,它的各个实例对象又分别 ...

随机推荐

  1. delphi 6数据库连接之长短模式(sqlserver)

    delphi 6数据库连接之长短模式(sqlserver) 标签: delphi数据库 2015-08-12 20:59 351人阅读 评论(0) 收藏 举报  分类: delphi(3)  版权声明 ...

  2. 自适应XAML布局经验总结 (一)原则和页面结构设计

    XAML布局回顾 Grid和StackPanel是核心布局,尤其以Grid最为重要. Grid是网格布局,XAML的设计者有可能参考了Html里的Table设计了Grid布局,但进行了改进.Html中 ...

  3. 知物由学 | 未来安全隐患:AI的软肋——故意欺骗神经网络

     本文由  网易云发布. “知物由学”是网易云易盾打造的一个品牌栏目,词语出自汉·王充<论衡·实知>.人,能力有高下之分,学习才知道事物的道理,而后才有智慧,不去求问就不会知道.“知物由学 ...

  4. JQuery Mobile - 解决切换页面时,闪屏,白屏等问题

    在点击链接,切换页面时候,总是闪屏,感觉很别扭,看起来不舒服,怎么解决这个问题?方法很简单,就是在每个页面的meta标签内定义user-scalable的属性为 no! <meta name=& ...

  5. Yes,I know the way to learn Ens !

    In recent years, translation has gone out of fashion as a way to learn a new language. A lot of peop ...

  6. 隐藏导航栏,偏移20PX

    1:让ViewController在NavigationBar下面开始布局. automaticallyAdjustsScrollViewInsets作用 当Controller上存在唯一一个UISc ...

  7. python 匿名函数 lambda 的使用

    在python中,lambda允许用户快速定义单行函数,当然用户也可以按照典型的函数定义完成函数.lambda的目的就是简化用户定义使用函数的过程. In [6]: s = lambda x: x+1 ...

  8. sublime 把 tab 转成 4 个空格

    Preferences -> Settings-User {    "tab_size":4,    "translate_tabs_to_spaces" ...

  9. JavaScript定时器作业

    JavaScript定时器作业 <!DOCTYPE html> <html lang="zh-CN"> <head> <meta char ...

  10. 酷!美国国家安全局(NSA)开源了逆向工程工具 Ghidra

    简评:2019 RSA 大会期间,NSA 正式发布了这个工具.免费 + 开源,真的有吸引力,据说体验可以和 IDA 一较高下. Ghidra 是由美国国家安全局(NSA)研究理事会创建和维护的软件逆向 ...