Golang基础笔记十六之反射
本文首发于公众号:Hunter后端
原文链接:Golang基础笔记十六之反射
反射可以用于程序在运行时检查、修改自身类型和值,主要通过 reflect 包实现。
首先,我们提出一个需求,要打印出一个结构体 struct 的各个字段及其对应的标签数据,按照当前的笔记内容是无法解决该问题的,但是我们可以使用反射操作来完成。
以下是本篇笔记目录:
- 变量的类型和值
- 修改变量的值
- 遍历结构体字段
- 动态调用函数
1、变量的类型和值
先引入 reflect 模块:
import (
"reflect"
)
我们可以通过 reflect.TypeOf() 获取变量的类型:
var x float64 = 3.5
t := reflect.TypeOf(x)
返回的 t 是 Type 接口,我们可以进一步调用 t 的方法来获取类型信息:
// 变量的类型名称:
fmt.Println("x 的类型名称是: ", t.Name())
// 判断类型的类别:
fmt.Println("x 的类型是否是 float64: ", t.Kind() == reflect.Float64)
获取变量的值信息:
v := reflect.ValueOf(x)
fmt.Println("value: ", v.Float() == 3.5)
2、修改变量的值
如果要修改这个变量的值,我们需要用到指针,以下是操作示例:
var x float64 = 3.5
// 这里获取的是变量的地址的值,如果直接 reflect.ValueOf(x) 获取的是 x 的副本
p := reflect.ValueOf(&x)
// Elem() 方法获取指针指向的实际值,是解引用的操作
v := p.Elem()
// 重新赋值的操作
v.SetFloat(4.9)
fmt.Println("new value: ", x)
3、遍历结构体字段
我们先定义一个结构体如下:
type Person struct {
Id int `json:"id" form:"id"`
Name string `json:"name"`
}
打印一个 Person 示例各个字段的名称及其值的操作如下:
p := Person{
Id: 1,
Name: "hunter",
}
t := reflect.TypeOf(p)
v := reflect.ValueOf(p)
for i := 0; i < t.NumField(); i++ {
field := t.Field(i)
value := v.Field(i)
fmt.Printf("field_name:%s, field_type:%s, value:%v\n", field.Name, field.Type, value.Interface())
}
在这里,我们通过 t.NumField() 方法获取到 p 的字段个数,并使用 t.Field(i) 和 v.Field(i) 获取到对应字段类型和值。
接着对于每个 field 和 value,我们可以打印出对应的字段名称,字段类型和值。
我们还可以使用 field.Tag.Get() 的方式获取到字段标签的值:
fmt.Printf("json_tag:%s, form_tag:%s\n", field.Tag.Get("json"), field.Tag.Get("form"))
如果后续我们介绍 Golang 的 validator 模块,可以了解到,validator 就是通过 struct 定义的标签使用反射来对字段值进行验证的。
4、动态调用函数
我们还可以使用反射来动态调用函数,比如某个函数如下:
func Add(a, b int) int {
return a + b
}
使用反射动态调用的操作如下:
func main() {
targetFunc := reflect.ValueOf(Add)
args := []reflect.Value{reflect.ValueOf(2), reflect.ValueOf(5)}
result := targetFunc.Call(args)
fmt.Println("动态调用 Add 函数,result: ", result[0].Int())
}
注意:虽然反射可以为我们提供一些便利的操作,但是代码的可读性和可维护性会降低,且会降低性能,需要在实际生产中谨慎使用。
Golang基础笔记十六之反射的更多相关文章
- Bootstrap <基础二十六>进度条
Bootstrap 进度条.在本教程中,你将看到如何使用 Bootstrap 创建加载.重定向或动作状态的进度条. Bootstrap 进度条使用 CSS3 过渡和动画来获得该效果.Internet ...
- python3.4学习笔记(十六) windows下面安装easy_install和pip教程
python3.4学习笔记(十六) windows下面安装easy_install和pip教程 easy_install和pip都是用来下载安装Python一个公共资源库PyPI的相关资源包的 首先安 ...
- Django笔记十六之aggregate聚合操作
本文首发于微信公众号:Hunter后端 原文链接:Django笔记十六之aggregate聚合操作 这一篇笔记介绍一下关于聚合的操作,aggregate. 常用的聚合操作比如有平均数,总数,最大值,最 ...
- css3基础教程十六变形与动画animation
前面我们讲过的变形与动画一般都是通过鼠标的单击.获得焦点,被点击或对元素进行一定改变后以后触发效果的,那么有没有像Flash一样自动播放的动画效果呢?答案当然是肯定的,这就是我们今天要讲到的anima ...
- linux基础-第十六单元 yum管理RPM包
第十六单元 yum管理RPM包 yum的功能 本地yum配置 光盘挂载和镜像挂载 本地yum配置 网络yum配置 网络yum配置 Yum命令的使用 使用yum安装软件 使用yum删除软件 安装组件 删 ...
- MYSQL基础笔记(六)- 数据类型一
数据类型(列类型) 所谓数据烈性,就是对数据进行统一的分类.从系统角度出发时为了能够使用统一的方式进行管理,更好的利用有限的空间. SQL中讲数据类型分成三大类:1.数值类型,2.字符串类型和时间日期 ...
- (C/C++学习笔记) 十六. 预处理
十六. 预处理 ● 关键字typeof 作用: 为一个已有的数据类型起一个或多个别名(alias), 从而增加了代码的可读性. typedef known_type_name new_type_nam ...
- Java基础学习笔记十六 集合框架(二)
List List接口的特点: 它是一个元素存取有序的集合.例如,存元素的顺序是11.22.33.那么集合中,元素的存储就是按照11.22.33的顺序完成的. 它是一个带有索引的集合,通过索引就可以精 ...
- 文件的上传Commons FileUpload(web基础学习笔记十六)
一.表单设置 <form action="<%=request.getContextPath()%>/jsp/admin/doAdd.jsp" enctype=& ...
- Golang基础(5):Go语言反射规则
Go语言反射规则 - The Laws of Reflection 转:http://my.oschina.net/qbit/blog/213720 原文地址:http://blog.golang.o ...
随机推荐
- Markdown 使用十分钟入门
Markdown 十分钟入门 标题 标题前#+空格 支持6级标题 输入样式#+空格:##+空格:以此类推, *注意标题输入的#前面不能有空格 字体 斜体 # 这里不要空格 _斜体_ *加一个* 字体加 ...
- 用 Tarjan 算法求解有向图的强连通分量
图论中的连通性概念是许多算法与应用的基础.当我们研究网络结构.依赖关系或路径问题时,理解图中的连通性质至关重要.对于不同类型的图,连通性有着不同的表现形式和算法解决方案. 无向图与有向图的连通性 在无 ...
- Web前端入门第 60 问:JavaScript 各种数组定义与数组取值方法
数组可以算是程序里面最常用的数据结构了,但凡网页上任何一个列表数据,基本都是以数组的形式存在,像表格.banner图.菜单列表.商品列表,分类列表等等,在前端领域都是以数组处理. 数组的定义 JS 的 ...
- Java 把列表元素拼接字符串
摘要:使用 Java Collectors.joining等方法把List中的所有元素通过指定的分隔符拼接为字符串. 目录 综述 使用For循环 StringUtils.join 函数 Collect ...
- gitlabrunner之executor配置拉取镜像的账户密码
docker executor $ cat config.toml ...... [[runners]] environment = ["DOCKER_AUTH_CONFIG={\" ...
- APEX实战第4篇:如何把APEX程序变成“移动端APP”?
因为使用手机登录APEX程序时,每次都要先到手机浏览器的入口感觉不方便且不专业,所以能不能像APP那样直接点击进入呢? 最简单的方式,就是使用PWA来实现类似APP程序一样的移动端登录. PWA本身配 ...
- Hack 说明
在今天的模拟赛中,部分同学由于对出现某个数在模 \(1000000007\) 意义下为 \(0\) 的情况不规范被 Hack. Hack 原理:开始时有 \(2\) 个 \(1\),先都加到 \(10 ...
- 支持向量机(SVM)分类
支持向量机(Support Vector Machine,SVM)是一种经典的监督学习算法,主要用于分类任务,也可扩展到回归问题(称为支持向量回归,SVR).其核心思想是通过寻找一个最优超平面,最 ...
- dotnet (.Net) Core在不是Web 项目中使用HttpClientFactory正确用法
在不是web 项目中也不是Api 中使用 HttpClientFactory 先需要添加 Microsoft.Extensions.DependencyInjection.Abstractions M ...
- css 给Input 左侧添加图标
background-image: url(../Content/Pc/img/IC_search.png); background-repeat: no-repeat; background-pos ...