reflect.Valueof 到底是个什么?

反射值对象(reflect.Value)提供一系列方法进行零值和空判定,如下表所示。

反射值对象的零值和有效性判断方法
方 法 说 明
IsNil() bool 返回值是否为 nil。如果值类型不是通道(channel)、函数、接口、map、指针或 切片时发生 panic,类似于语言层的v== nil操作
IsValid() bool 判断值是否有效。 当值本身非法时,返回 false,例如 reflect Value不包含任何值,值为 nil 等。

下面的例子将会对各种方式的空指针进行 IsNil() 和 IsValid() 的返回值判定检测。同时对结构体成员及方法查找 map 键值对的返回值进行 IsValid() 判定,参考下面的代码。

代码一:
反射值对象的零值和有效性判断:

  1. package main
  2. import (
  3. "fmt"
  4. "reflect"
  5. )
  6. func main() {
  7. // *int的空指针
  8. var a *int
  9. fmt.Println("var a *int:", reflect.ValueOf(a).IsNil())
  10. // nil值
  11. fmt.Println("nil:", reflect.ValueOf(nil).IsValid())
  12. // *int类型的空指针
  13. fmt.Println("(*int)(nil):", reflect.ValueOf((*int)(nil)).Elem().IsValid())
  14. // 实例化一个结构体
  15. s := struct{}{}
  16. // 尝试从结构体中查找一个不存在的字段
  17. fmt.Println("不存在的结构体成员:", reflect.ValueOf(s).FieldByName("").IsValid())
  18. // 尝试从结构体中查找一个不存在的方法
  19. fmt.Println("不存在的结构体方法:", reflect.ValueOf(s).MethodByName("").IsValid())
  20. // 实例化一个map
  21. m := map[int]int{}
  22. // 尝试从map中查找一个不存在的键
  23. fmt.Println("不存在的键:", reflect.ValueOf(m).MapIndex(reflect.ValueOf(3)).IsValid())
  24. }

代码输出如下:

var a *int: true
nil: false
(*int)(nil): false
不存在的结构体成员: false
不存在的结构体方法: false
不存在的键: false

代码说明如下:

  • 第 11 行,声明一个 *int 类型的指针,初始值为 nil。
  • 第 12 行,将变量 a 包装为 reflect.Value 并且判断是否为空,此时变量 a 为空指针,因此返回 true。
  • 第 15 行,对 nil 进行 IsValid() 判定(有效性判定),返回 false。
  • 第 18 行,(*int)(nil) 的含义是将 nil 转换为 *int,也就是*int 类型的空指针。此行将 nil 转换为 *int 类型,并取指针指向元素。由于 nil 不指向任何元素,*int 类型的 nil 也不能指向任何元素,值不是有效的。因此这个反射值使用 Isvalid() 判断时返回 false。
  • 第 21 行,实例化一个结构体。
  • 第 24 行,通过 FieldByName 查找 s 结构体中一个空字符串的成员,如成员不存在,IsValid() 返回 false。
  • 第 27 行,通过 MethodByName 查找 s 结构体中一个空字符串的方法,如方法不存在,IsValid() 返回 false。
  • 第 30 行,实例化一个 map,这种写法与 make 方式创建的 map 等效。
  • 第 33 行,MapIndex() 方法能根据给定的 reflect.Value 类型的值查找 map,并且返回查找到的结果。

IsNil() 常被用于判断指针是否为空;IsValid() 常被用于判定返回值是否有效。

代码二:

    a := map[string]int{}
    a["aa"] = 2
    b := reflect.ValueOf(a).MapIndex(reflect.ValueOf("aa"))
    c := b.Kind()
    fmt.Println(c == reflect.Int)//打印true

反射 go的更多相关文章

  1. 隐私泄露杀手锏 —— Flash 权限反射

    [简版:http://weibo.com/p/1001603881940380956046] 前言 一直以为该风险早已被重视,但最近无意中发现,仍有不少网站存在该缺陷,其中不乏一些常用的邮箱.社交网站 ...

  2. Java学习之反射机制及应用场景

    前言: 最近公司正在进行业务组件化进程,其中的路由实现用到了Java的反射机制,既然用到了就想着好好学习总结一下,其实无论是之前的EventBus 2.x版本还是Retrofit.早期的View注解框 ...

  3. 关于 CSS 反射倒影的研究思考

    原文地址:https://css-tricks.com/state-css-reflections 译者:nzbin 友情提示:由于演示 demo 的兼容性,推荐火狐浏览.该文章篇幅较长,内容庞杂,有 ...

  4. 编写高质量代码:改善Java程序的151个建议(第7章:泛型和反射___建议106~109)

    建议106:动态代理可以使代理模式更加灵活 Java的反射框架提供了动态代理(Dynamic Proxy)机制,允许在运行期对目标类生成代理,避免重复开发.我们知道一个静态代理是通过主题角色(Prox ...

  5. 运用Mono.Cecil 反射读取.NET程序集元数据

    CLR自带的反射机智和API可以很轻松的读取.NET程序集信息,但是不能对程序集进行修改.CLR提供的是只读的API,但是开源项目Mono.Cecil不仅仅可以读取.NET程序集的元数据,还可以进行修 ...

  6. .NET面试题系列[6] - 反射

    反射 - 定义,实例与优化 在面试中,通常会考察反射的定义(操作元数据),可以用反射做什么(获得程序集及其各个部件),反射有什么使用场景(ORM,序列化,反序列化,值类型比较等).如果答得好,还可能会 ...

  7. .NET基础拾遗(4)委托、事件、反射与特性

    Index : (1)类型语法.内存管理和垃圾回收基础 (2)面向对象的实现和异常的处理基础 (3)字符串.集合与流 (4)委托.事件.反射与特性 (5)多线程开发基础 (6)ADO.NET与数据库开 ...

  8. C++的性能C#的产能?! - .Net Native 系列五:.Net Native与反射

    此系列系小九的学堂原创翻译,翻译自微软官方开发向导,一共分为六个主题.本文是第五个主题:.Net Native与反射. 向导文链接:<C++的性能C#的产能?! - .Net Native 系列 ...

  9. [源码]Literacy 快速反射读写对象属性,字段

    Literacy 说明 Literacy使用IL指令生成方法委托,性能方面,在调用次数达到一定量的时候比反射高很多 当然,用IL指令生成一个方法也是有时间消耗的,所以在只使用一次或少数几次的情况,不但 ...

  10. SI与EMI(一) - 反射是怎样影响EMI

    Mark为期两天的EMC培训中大概分成四个时间差不多的部分,简单来说分别是SI.PI.回流.屏蔽.而在信号完整性的书籍中,也会把信号完整性分为:1.信号自身传输的问题(反射,损耗):2.信号与信号之间 ...

随机推荐

  1. 【Day2】2.函数

     视频地址(全部) https://edu.csdn.net/course/detail/26057 课件地址(全部) https://download.csdn.net/download/gentl ...

  2. 【转】make menuconfig/.config/Kconfig解析

    当执行#make menuconfig时会出现内核的配置界面,所有配置工具都是通过读取"arch/$(ARCH)/Kconfig"文件来生成配置界面,这个文件就是所有配置的总入口, ...

  3. Android 计算器制作 2.注册View 构建函数

    鄙人新手 整了 快两天 终于搞定了.. 1.首先是MainActivity 中 在Oncreate函数中 注册 2.按+ 或者 - 号 来分成两大字符串 s1 和 s2 再将s2 分为更小的s1 和 ...

  4. Spring AOP学习笔记(1)-概念

    1.Aspect 横切在多个类的一个关注点,在Spring AOP中,aspect实现是一个规则的类或@Aspect标注的规则类.例如:事务管理 2.Join point 程序执行过程中的一个点,例如 ...

  5. Python——变量的作用域

    原创声明:本文系博主原创文章,转载及引用请注明出处. 1. 在编程语言中,变量都有一定的作用域,用来限定其生命周期,且不同类型的变量作用域不同. 在Python中解释器引用变量的顺序(优先级)为:当前 ...

  6. pycharm 如何自动添加头注释,比如时间,作者信息等

    查找路径:File->settings->Editor->File and Code Templates->Python Script #!/usr/bin/env pytho ...

  7. hive日期函数-Demo(二)

    需求:某资产近一个月的资产值 比如:今天是2018年2月28日,近一个月若是按照自然月来算,那么是2018年2月1日至2018年2月28日.最终需要的日期格式为:yyyyMMdd. 当日时间戳 uni ...

  8. Monkey使用详情

    https://blog.csdn.net/zhangmeng1314/article/details/82699316 比如使用 adb shell input keyevent <keyco ...

  9. jquery animate()方法 语法

    jquery animate()方法 语法 作用:animate() 方法执行 CSS 属性集的自定义动画.该方法通过CSS样式将元素从一个状态改变为另一个状态.CSS属性值是逐渐改变的,这样就可以创 ...

  10. angular打包(三):pkg

    希望打包成1个web服务,运行exe,启动 angular,供浏览器显示. 问题分析: 其实angular编译后,都是静态文件了.只需要打包express,让express可以以exe的形式运行就可以 ...