一、反射

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. 【转载】Linux虚拟化KVM-Qemu分析(五)之内存虚拟化

    原文信息 作者:LoyenWang 出处:https://www.cnblogs.com/LoyenWang/ 公众号:LoyenWang 版权:本文版权归作者和博客园共有 转载:欢迎转载,但未经作者 ...

  2. Django基本数据库操作

    Django基本数据库操作 @ 目录 Django基本数据库操作 ‍内容一:基本数据库配置 ‍内容二:ORM基本操作 ‍内容一:基本数据库配置 Django是一个流行的Python Web框架,它可以 ...

  3. FreeRTOS 基于 ARMv8-M 对 MPU 的应用

    一.前言 ARMv8-M 支持 MPU,FreeRTOS 也添加了对这些 MPU 的应用代码.这里用来记录 FreeRTOS 对 MPU 应用方式的探究结果. 二.ArmV8-M MPU 介绍 ARM ...

  4. C#程序的启动显示方案(无窗口进程发送消息) - 开源研究系列文章

    今天继续研究C#的WinForm的实例显示效果. 我们上次介绍了Winform窗体的唯一实例运行代码(见博文:基于C#的应用程序单例唯一运行的完美解决方案 - 开源研究系列文章 ).这就有一个问题,程 ...

  5. React-Chat移动端聊天实例|react18 hooks仿微信App聊天界面

    基于react18+react-vant+zustand仿微信手机端聊天室ReactChat. react18-chat 一款使用最新react18.x hooks.zustand搭配react-va ...

  6. uniapp 地图如何添加?你要的教程来喽!

    地图在 app 中使用还是很广泛的,常见的应用常见有: 1.获取自己的位置,规划路线. 2.使用标记点进行标记多个位置. 3.绘制多边形,使用围墙标记位置等等. 此篇文章就以高德地图为例,以上述三个常 ...

  7. 京东搜索EE链路演进

    导读 搜索系统中容易存在头部效应,中长尾的优质商品较难获得充分的展示机会,如何破除系统的马太效应,提升展示结果的丰富性与多样性,助力中长尾商品成长是电商平台搜索系统的一个重要课题.其中,搜索EE系统在 ...

  8. xlsx和path的运用

    从后端获取Excel模板 app.get('/api/download-template', (req, res) => { const templatePath = path.join(__d ...

  9. DesignPattern-part1

    title: "modern C++ DesignPattern-Part1" date: 2018-04-03T16:06:33+08:00 lastmod: 2018-04-0 ...

  10. java循环自动生成简单图片

    import java.awt.*; import java.awt.font.FontRenderContext; import java.awt.geom.Rectangle2D; import ...