一、反射

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. Nginx获取用户真实IP

    Nginx获取用户真实IP地址 本人在一次项目中,使用Nginx需要获取到用户IP,本来可以很常规的获取的,可现实往往不常规,项目是前后端分离的,部署时,前端使用了Nginx进行了代理并转发,后端也使 ...

  2. MyBatis理论

    MyBatis简介 MyBatis是什么? MyBatis是一款优秀的持久层框架,一个ORM(对象关系映射)框架,它支持定制化SQL.存储过程以及高级映射.MyBaits避免了几乎所有JDBC代码和手 ...

  3. EntityCleanFramework

    EF几乎是按照领域的概念诞生,它可以和Clean结合(ECF是我新想出的名字).ECF 是为了统一业务架构开发方式,也可以说成在 微服务架构 中服务的通用开发方式.当有了统一开发方式后,协作将更上一层 ...

  4. 【博客重构之路】webman-admin安装指南

    原文地址[博客重构之路]webman-admin安装指南 视频地址[bilibili] webman是什么 webman是一款基于workerman开发的高性能HTTP服务框架.webman用于替代传 ...

  5. FreeSWITCH通过mod_mariadb原生连接MySQL

    前言 根据官方更新说明(https://freeswitch.org/confluence/display/FREESWITCH/FreeSWITCH+1.10.x+Release+notes),从1 ...

  6. Programming abstractions in C阅读笔记:p84-p87

    <Programming Abstractions In C>学习第43天,p84-p87总结. 一.技术总结 1.record record也称为structure(结构体),是一种数据 ...

  7. nlp入门(五)隐马尔科夫模型

    源码请到:自然语言处理练习: 学习自然语言处理时候写的一些代码 (gitee.com) 一.马尔科夫模型概念 1.1 马尔科夫模型:具有马尔可夫性质并以随机过程为基础的模型 1.2 马尔科夫性质:过去 ...

  8. 代码随想录算法训练营第二十九天| 491.递增子序列 46.全排列 47.全排列 II

      491.递增子序列 卡哥建议:本题和大家刚做过的 90.子集II 非常像,但又很不一样,很容易掉坑里.  https://programmercarl.com/0491.%E9%80%92%E5% ...

  9. vue3 甘特图(二):甘特图时间轴切换

    vue3 甘特图(二):gantt时间轴切换 1.固定时间轴缩放级别 gantt.config.scale_unit = "month"; //时间轴单位 gantt.config ...

  10. Salesforce LWC学习(四十五) lwc支持Console App控制Tab了

    本篇参考:https://help.salesforce.com/s/articleView?id=release-notes.rn_lwc_workspaceAPI.htm&release= ...