一、反射

1.1简介

Reflection(反射)在计算机中就是表示程序在运行期间能够探知自身结构的能力类型(类型信息、内存结构、更新变量、以及调用方法)

1.2使用场景

  • 函数的参数类型是interface{},需要在运行时对原始类型进行判断,针对不同的类型采取不同的处理方式。比如 类型断言,JSON序列化 json.Marshal(v interface{})。
type UserInfo struct {
Name string
Age int
Sex byte `json:"gender"`
}
user := UserInfo{
Name: "大猫",
Age: 18,
Sex: 1,
}
json.Marshal(user) //返回 {"Name":"大猫","Age":18,"gender":1}
  • 在运行时根据某些条件动态决定调用哪个函数,比如根据配置文件执行相应的算子函数。

1.3 反射的弊端

  • 代码难以阅读,难以维护。
  • 编译期间不能发现类型错误,覆盖测试难度很大,有些bug需要到线上运行很长时间才能发现,可能会造成严重用后果。
  • 反射性能很差,通常比正常代码慢一到两个数量级。在对性能要求很高,或大量反复调用的代码块里建议不要使用反射。

二、反射的基础数据类型

2.1 reflect.Type 中一些 获取类型相关的信息 的方法

type Type interface {
Align() int //Align返回该类型的值在内存中分配时的字节数。
FieldAlign() int //字段对齐(FieldAlign)返回在结构体中作为字段使用时的类型的值在结构体中作为一个字段使用时的字节数。
Method(int) Method //第i个方法
MethodByName(string) (Method, bool) //根据名称获取方法
NumMethod() int //方法的个数
Name() string //获取结构体名称
PkgPath() string //包路径(导入路径)
Size() uintptr //占用内存的大小(存储给定类型的字节大小,类似 unsafe.Sizeof())
String() string //获取字符串表述
Kind() Kind //返回该类型的特定类型 数据类型(种类 比type类型范围大)
Implements(u Type) bool //判断是否实现了某接口
AssignableTo(u Type) bool // 判断是否可赋值另外一种类型
ConvertibleTo(u Type) bool //判断能否转换为另外一种类型(即使返回true 也有可能转换时出现错误)
Comparable() bool // 类型的值是否可比较(即使返回true 也会出现比较问题比如interface type的值是可比较的,但如果它们的动态类型不具有可比性,则比较将出现问题。)
Elem() Type //解析指针
Field(i int) StructField //第i个成员
FieldByIndex(index []int) StructField //根据index路径获取嵌套成员(比如第i个成员是一个结构体或者接口这样的嵌套,想要获取其里面的第j个成员,index就要写成[]int{i,j)
FieldByName(name string) (StructField, bool) //根据名称获取成员
FieldByNameFunc(match func(string) bool) (StructField, bool) //
Len() int //容器的长度
NumIn() int //输出参数的个数
NumOut() int //返回参数的个数
}

2.2 reflect.Value 获取、修改原始数据类型里的值

type Value struct {
// 代表的数据类型
typ *rtype
// 指向原始数据的指针
ptr unsafe.Pointer flag
}

2.3 如何得到Type呢?通过TypeOf()得到Type类型。就可以使用reflect.Type()里面的方法

typeI := reflect.TypeOf(1234)
typeS := reflect.TypeOf("helloworld")
fmt.Println(typeI) //int
fmt.Println(typeS) //string
fmt.Println(typeI.Kind() == reflect.Int) //true
fmt.Println(typeS.Kind() == reflect.String) //true typeUser := reflect.TypeOf(&User{}) //这里的User就是自定义的空的结构体 : type User struct{}
fmt.Println(typeUser) //*User
fmt.Println(typeUser.Kind()) //ptr
fmt.Println(typeUser.Elem().Kind()) //struct

2.4 reflect.Type()里面方法 一些细致讲解(暂时还没写,以后在补连接)

2.5 如何获得Value?通过ValueOf()得到Value。

iValue := reflect.ValueOf(12345)
sValue := reflect.ValueOf("helloword")
userPtrValue := reflect.ValueOf(User{
Id: 1,
Name: "大猫",
Weight: 75,
Height: 1.72,
})
fmt.Println(iValue) //12345
fmt.Println(sValue) //helloword
fmt.Println(userPtrValue) //&{1 大猫 75 1.72}

2.6 reflect.Value()里面方法 一些细致讲解(暂时还没写,以后在补连接)

2.7 Value转Type

iValue := reflect.ValueOf(12345)
sValue := reflect.ValueOf("helloword")
userPtrValue := reflect.ValueOf(User{
Id: 1,
Name: "大猫",
Weight: 75,
Height: 1.72,
})
iType := iValue.Type()
sType := sValue.Type()
userType := userPtrValue.Type()
//在Type和相应Value上调用Kind()结果一样的
fmt.Println(iType.Kind() == reflect.Int, iValue.Kind() == reflect.Int, iType.Kind() == iValue.Kind())
fmt.Println(sType.Kind() == reflect.String, sValue.Kind() == reflect.String, sType.Kind() == sValue.Kind())
fmt.Println(userType.Kind() == reflect.Ptr, userPtrValue.Kind() == reflect.Ptr, userType.Kind() == userPtrValue.Kind())

后续,以后再补

go语言reflection反射的更多相关文章

  1. 代替Reflection(反射)的一些方法

    Reflection(反射)是深入学习.Net必须掌握的技能之一.最初学Reflection的时候,的确是被惊住了,原来还可以这样.只要给你一个Assembly, 你就能获取到其中所有的类型,根据类型 ...

  2. Java进阶之reflection(反射机制)——反射概念与基础

    反射机制是Java动态性之一,而说到动态性首先得了解动态语言.那么何为动态语言? 一.动态语言 动态语言,是指程序在运行时可以改变其结构:新的函数可以引进,已有的函数可以被删除等结构上的变化.比如常见 ...

  3. java学习--Reflection反射机制

    JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意方法和属性:这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制. ...

  4. 代替Reflection(反射)的一些方法(转)

    作者:JustRun 林肯: http://www.cnblogs.com/JustRun1983/p/3830764.html 代替Reflection(反射)的一些方法(转) 2014-07-08 ...

  5. 深度解密Go语言之反射

    目录 什么是反射 为什么要用反射 反射是如何实现的 types 和 interface 反射的基本函数 反射的三大定律 反射相关函数的使用 代码样例 未导出成员 反射的实际应用 json 序列化 De ...

  6. reflection反射

    reflection反射 动态和静态语言 动态语言 动态语言就是一类在运行时可以改变其结构的语言,通俗点说就是在运行时代码可以根据某些条件改变自身结构 主要动态语言:object-C,C#,JavaS ...

  7. go语言通过反射获取和设置结构体字段值的方法

    本文实例讲述了go语言通过反射获取和设置结构体字段值的方法.分享给大家供大家参考.具体实现方法如下: type MyStruct struct { N int } n := MyStruct{ 1 } ...

  8. Go语言之反射(一)

    反射 反射是指在程序运行期对程序本身进行访问和修改的能力.程序在编译时,变量被转换为内存地址,变量名不会被编译器写入到可执行部分.在运行程序时,程序无法获取自身的信息.支持反射的语言可以在程序编译期将 ...

  9. Go语言 8 反射

    文章由作者马志国在博客园的原创,若转载请于明显处标记出处:http://www.cnblogs.com/mazg/ Go学习群:415660935 8.1概念和作用 Reflection(反射)在计算 ...

  10. Java之reflection(反射机制)——通过反射操作泛型,注解

    一.反射操作泛型(Generic) Java采用泛型擦除机制来引入泛型.Java中的泛型仅仅是给编译器Javac使用的,确保数据的安全性和免去强制类型转换的麻烦.但是编译一旦完成,所有和泛型有关的类型 ...

随机推荐

  1. C语言指针--一级指针

    文章目录 前言 一.什么是指针 二.一级指针的使用 1.一级指针的创建 2.指针的赋值 3.&是什么 4.一维指针的使用 4.1 `变量` 和 `*变量` 4.2 输出指针变量内容 4.3 改 ...

  2. Hive安装与启动

    一.mysql安装 在配置Hive之前一般都需要安装和配置MySQL,因为Hive为了能操作HDFS上的数据集,那么他需要知道数据的切分格式,如行列分隔符,存储类型,是否压缩,数据的存储地址等信息. ...

  3. 关于quartus II的导入以前的工程,QSF文件出现的错误的解决方案。

    在有时候打开以前的工程,或者别人做好的例程会遇到一些报错信息.具体报错信息如下: 报错信息语句行: 在文件QSF文件中有几行出错,显示错误读取,即不能打开工程.打开文件发现该几行的PIN 使能信号处于 ...

  4. 需求太多处理不过来?MoSCoW模型帮你

    一.MoSCoW模型是什么 MoSCoW模型是在项目管理.软件开发中使用的一种排序优先级的方法,以便开发人员.产品经理.客户对每个需求交付的重要性达成共识. MoSCoW是一个首字母缩略词,代表: M ...

  5. vue vue-simple-uploader 前端的简单使用

    前言 因为项目需要上传大文件tif图,考虑使用分片上传. 1.安装 npm install vue-simple-uploader --save 2.main.js中初始化 import upload ...

  6. 加密算法解析:MD5、DES和RAS的工作原理与特点

    一.MD5不可逆加密 1.1-理解MD5 MD5公开的算法,任何语言实现后其实都是一样的.通用的 不可逆加密:原文--加密--密文,密文无法解密出原文 1.2-MD5封装 using System.I ...

  7. go-zero 是如何实现令牌桶限流的?

    原文链接: 上一篇文章介绍了 如何实现计数器限流?主要有两种实现方式,分别是固定窗口和滑动窗口,并且分析了 go-zero 采用固定窗口方式实现的源码. 但是采用固定窗口实现的限流器会有两个问题: 会 ...

  8. docker网络 bridge 与overlay 模式

    转载请注明出处: 1.bridge网络模式 工作原理:  在Bridge模式中,Docker通过创建一个虚拟网络桥接器(bridge)将容器连接到主机上的物理网络接口.每个容器都会被分配一个IP地址, ...

  9. Vue 框架下提升加载速度的一些实战经验分享

    现在前端的框架有很多,甚至两只手已经数不过来,当然也完全没必要全部都学,还是应该深入的学习一两个被广泛使用的就好.其实我和大部分同学的想法一致,认为最值得我们深究的还是主流的 Vue 和 React. ...

  10. .NET Core基础到实战案例零碎学习笔记

    前言:前段时间根据 [老张的哲学] 大佬讲解的视频做的笔记,讲的很不错.此文主要记录JWT/DI依赖注入/AOP面向切面编程/DTO/解决跨域等相关知识,还包含一些.NET Core项目实战的一些案例 ...