一、反射

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. 详解同为4800W像素的相机传感器,三星GM1和索尼IMX586区别在哪里?

    数字影像之父Bryce Bayer基于RGB模式,通过在感光元件前加上一个滤镜的方法终于实现了彩色照片.Bayer滤镜跨出了照片从黑白到彩色的一大步,但是对于挑剔的人眼来说,每个像素只有一个颜色是远远 ...

  2. 基于Avalonia 11.0.0+ReactiveUI 的跨平台项目开发1-通用框架

    基于Avalonia 11.0.0+ReactiveUI 的跨平台项目开发1-通用框架 Avalonia简介: Avalonia是.NET的一个跨平台UI框架,提供了一个灵活的样式系统,支持广泛的操作 ...

  3. 2023ccpc大学生程序设计竞赛-wh

    对于大一的我,只听说线下大型比赛,而第一次参加也必然心情激动,生为大一,由于没有参赛经历,所有不知道参赛技巧,所以三个人像个无头苍蝇一样,跟着榜单做,我作为写码的,其他两名队友负责思路和想法,第一道签 ...

  4. (转)[Android测试] Android Studio+Appium+Java+Windows 自动化测试之二:Appium环境安装搭建

    一.需要下载安装的东西 1. 文件下载 网上也有挺多安装教程的,这里我提供我的安装方法.Win10 64位.一些文件我在后面打包. 2016.9.12号本人安装记录. SDK: 由于我是搞Androi ...

  5. 青少年CTF-Web-帝国CMS1-3通关记录

    0x01说明 本次进通过平台内题目进行,非真实环境. 帝国CMS01 首先下发题目链接 我们首先先找后台看看 后台地址为/e/admin/ 随后,经过dirsearch进行扫描,得到了一个www.zi ...

  6. [etcd]简介与安装

    简介 etcd是一个采用Raft协议实现强一致性的分布式键值数据库,它提供了一种可靠的方式存储需要被分布式系统或机器集群访问的数据. 常见使用场景:服务注册与发现.键值对存储.消息发布和订阅.分布式锁 ...

  7. [golang]使用gocron编写定时任务

    前言 linux自带的crontab默认情况下只能精确到分钟,没法执行秒级任务.当然,也不是不行,比如: * * * * * for i in $(seq 1 11);do echo hello &g ...

  8. 【pandas小技巧】--字符串转数值

    字符串转数字的用途和场景很多,其中主要包括以下几个方面: 数据清洗:在进行数据处理时,经常会遇到一些数据类型不匹配的问题,比如某些列中的字符串类型被误认为是数字类型,此时需要将这些字符串类型转换为数字 ...

  9. MongoDB索引操作和执行计划Explain()详解

    一.索引操作 说明,下面的内容举例时,以"dailyTrip"collection为例. 字段内容如下: { "_id" : ObjectId("63 ...

  10. shell编程之存储读写测试实战脚本

    Shell编程是一种在命令行环境中编写程序的技术,常用于Linux和Unix系统.它主要使用Shell脚本语言来编写程序.Shell编程常用于系统管理.自动化任务.批处理等领域. 常用的Shell脚本 ...