golang反射
要点
- 1.变量
- 2.反射
- 3.结构体反射
- 4.反射总结以及应用场景
一、变量介绍
1.变量的内在机制
- A、类型信息,这部分是元信息,是预定义好的
- B、值类型,这部分是程序运行过程中,动态改变的
var arr [10]int
arr[0] = 10
arr[1] = 20
arr[2] = 30
arr[3] = 40
type Animal struct {
Name string
age int
}
var a Animal
二、反射介绍
1.反射与空接口
- A、空接口可以存储任何类型的变量
- B、那么给你一个空接口,怎么知道里面存储的是什么东西?
- C、在运行时动态获取一个变量的类型信息和值信息,就叫反射
2.反射介绍
- A.内置包 reflect
- B.获取类型信息: reflect.TypeOf
- C.获取值信息: reflect.ValueOf
3.基本数据类型分析
package main
import (
"fmt"
"reflect"
)
func main() {
var x float64 = 3.4
fmt.Println("type:", reflect.TypeOf(x))
}
4.Type.Kind(),获取变量的类型
package main
import (
"fmt"
"reflect"
)
func main() {
var x float64 = 3.4
t := reflect.TypeOf(x)
fmt.Println("type:", t.Kind())
}
5.reflect.ValueOf, 获取变量的值相关信息
var x float64 = 3.4
v := reflect.ValueOf(x)
// 和reflect.TypeOf功能是一样的
fmt.Println("type:", v.Type())
fmt.Println("kind is float64:",v.Kind() == reflect.Float64)
fmt.Println("value:",v.Float())
6.通过反射设置变量的值
var x float64 = 3.4
v := reflect.ValueOf(x)
fmt.Println("type:", v.Type())
fmt.Println("kind is float64:",v.Kind() == reflect.Float64)
v.SetFloat(6.8)
fmt.Println("value:", v.Float())
panic,程序崩溃了。
7.通过反射设置变量的值
var x float64 = 3.4
// 传地址进去,不传地址的话,改变的是副本的值
// 所以在reflect包里直接崩溃了!!!!
v := reflect.ValueOf(&x)
fmt.Println("type:", v.Type())
fmt.Println("kind is float64:", v.Kind() == reflect.Float64)
v.SetFloat(6.8)
fmt.Println("value:",v.Float())
我靠,还报错.
8.通过反射设置变量的值
var x float64 = 3.4
// 传地址进去,不传地址的话,改变的是副本的值
// 所以在reflect包里直接崩溃了!!!!
v := reflect.ValueOf(&x)
fmt.Println("type:",v.Type())
fmt.Println("kind is float64:",v.Kind() == reflect.Float64)
// 通过Elem()获取指针指向的变量,从而完成赋值操作。
// 正常操作是通过*号来解决的,比如
// var *p int = new(int)
// *p = 100
v.Elem().SetFloat(6.8)
fmt.Println("value:",v.Float())
9.通过反射设置变量的值
var x float64 = 3.4
v := reflect.ValueOf(&x)
fmt.Println("type:",v.Type())
fmt.Println("kind is float64:",v.Kind() == reflect.Float64)
v.Elem().SetInt(100)
fmt.Println("value:",v.Float())
// 我靠,又犯贱了。
结构体反射
1.获取结构体类型相关信息
package main
import (
"fmt"
"reflect"
)
type S struct {
A int
B string
}
func main() {
s := S{23, "skidoo"}
v := reflect.ValueOf(s)
t := v.Type()
for i := 0; i < v.NumField(); i++ {
f := v.Field(i)
fmt.Printf("%d: %s %s = %v\n",i,t.Field(i).Name, f.Type(), f.Interface())
}
}
2.获取结构体类型相关信息
package main
import (
"fmt"
"reflect"
)
type S struct {
A int
B string
}
func main() {
s := S{23, "skidoo"}
v := reflect.ValueOf(s)
t := v.Type()
for i := 0; i < v.NumField(); i++ {
f := v.Field(i)
fmt.Printf("%d: %s %s = %v\n",i,t.Field(i).Name, f.Type(), f.Interface())
}
}
3.设置结构相关字段的值
package main
import (
"fmt"
"reflect"
)
type S struct {
A int
B string
}
func main() {
s := S{23, "skidoo"}
v := reflect.ValueOf(&s)
t := v.Type()
v.Elem().Field(0).SetInt(100)
for i := 0; i < v.Elem().NumField(); i++ {
f := v.Elem().Field(i)
fmt.Printf("%d: %s %s = %v\n",i, t.Elem().Field(i).Name, f.Type(), f.Interface())
}
}
4.获取结构体的方法信息
package main
import (
"fmt"
"reflect"
)
type S struct {
A int
B string
}
func (s *S) Test() {
fmt.Println("this is a test")
}
func main() {
s := S{23, "skidoo"}
v := reflect.ValueOf(&s)
t := v.Type()
v.Elem().Field(0).SetInt(100)
fmt.Println("method num:", v.NumField())
for i := 0; i < v.NumMethod(); i++ {
f := t.Method(i)
fmt.Printf("%d method, name:%v, type:%v\n", i, f.Name, f.Type)
}
}
5.调用结构体中的方法
package main
import (
"fmt"
"reflect"
)
type S struct {
A int
B string
}
func (s *S) Test() {
fmt.Println("this is a test")
}
func (s *S) SetA(a int) {
s.A = a
}
func main() {
s := S{23, "skidoo"}
v := reflect.ValueOf(&s)
m := v.MethodByName("Test")
var args1 []reflect.Value
m.Call(args1)
setA := v.MethodByName("SetA")
var args2 []reflect.Value
args2 = append(args2, reflect.ValueOf(100))
setA.Call(args2)
fmt.Printf("s:%#v\n",s)
}
6.获取结构体中的tag信息
package main
import (
"fmt"
"reflect"
)
type S struct {
F string `species:"gopher" color:"blue" json:"f"`
}
func main() {
s := S{}
st := reflect.TypeOf(s)
field := st.Field(0)
fmt.Println(field.Tag.Get("color"), field.Tag.Get("species"), field.Tag.Get("json"))
}
7.应用场景
在运行时动态获取一个变量的类型信息和值信息就叫做反射
- 1.序列化和反序列化,比如json, protobuf等各种数据协议
- 2.各种数据库的ORM, 比如gorm, sqlx等数据库中间件
- 3.配置文件解析相关的库,比如ymal ini等。
golang反射的更多相关文章
- golang反射初试
golang反射来自Go AST(Abstract Syntax Tree). reflect操作更多像traverse AST. t := reflect.TypeOf(obj) 使用TypeOf( ...
- golang 反射应用(二)
golang反射应用(二) package test import ( "reflect" "testing" ) //定义适配器 func TestRefle ...
- Golang反射机制
Go反射机制:在编译不知道类型的情况下,可更新变量.在运行时查看值.调用方法以及直接对它们的布局进行操作. 为什么使用反射 有时需要封装统一接口对不同类型数据做处理,而这些类型可能无法共享同一个接口, ...
- [golang]反射的用处--代码自动生成
背景: go语言处理db.json的时候,具体代码的变量定义和db字段.json输出的时候可能不一样. 这个时候,我们需要用tag的方式来进行定义. 例如: type MyStruct struct ...
- GOLANG 反射法则
译自[blog.golang.org/laws-of-reflection] 在计算机中, 反射是程序通过类型,检测到它自己的结构能力:是一种元编程程:也是一个具大的混淆点 在本文中,我们将通过解释反 ...
- golang 反射
参考:|--http://blog.51cto.com/speakingbaicai/1707637 |--https://studygolang.com/articles/6324 反射是在gola ...
- golang 反射中调用方法
反射中调用函数 众所周知,golang中的函数是可以像普通的int.float等类型变量那样作为值的,例如: package main import "fmt" func hell ...
- GO开发[六]:golang反射(reflect)
反射 反射:可以在运行时动态获取变量的相关信息 Import ("reflect") reflect.TypeOf,获取变量的类型,返回reflect.Type类型 refle ...
- golang反射举例
反射就是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意方法和属性:并且能改变它的属性. package main import ( "f ...
随机推荐
- Python字符编码与转换
需知: .在python2默认编码是ASCII, python3里默认是unicode .unicode 分为 utf-(占4个字节),utf-(占两个字节),utf-(占1-4个字节), ...
- 动态嵌套form,使用Stimulus Js库(前后端不分离)
我的git代码:https://github.com/chentianwei411/nested_form-Stimulus- Stimulus: https://www.cnblogs.co ...
- linux环境下 python环境import找不到自定义的模块
linux环境下 python环境import找不到自定义的模块 问题现象: Linux环境中自定义的模块swport,import swport 出错.swport模块在/root/sw/目录下. ...
- 安装weblogic
附:wls1036_generic.jar 链接:https://pan.baidu.com/s/1W5g-SHeKL96yrOeDKJJoxw 提取码:vxft 注:以下安装步骤是一个前辈整理的,我 ...
- .zip压缩版MySql的安装( )
Mysql解压缩版下载安装过程 1.进入https://www.mysql.com/downloads/官网进行mysql的下载 找到downloads首页最下方MySQL Community Edi ...
- mybatis获取insert插入之后的id
一.为什么要获取insert的id 写了测试类测试插入,插入之后用select查询出来进行Assert 插入成功后,不管Select对比的结果成功还是失败,都希望删除掉测试插入的结果 二.运行环境 m ...
- LInux下几种定时器的比较和使用
在数据通信过程中,会遇到对数据发送时间的格式要求.所以要在应用中根据实际要求选择不同的定时器,就要考虑到几种应用定时器的特点. 定时器文章参考 一般而言有, 1.sleep,usleep和nanosl ...
- argument 1 must be 2-item sequence, not int
看了 https://blog.csdn.net/qq_18250439/article/details/80872425 的说明,才明白为什么错了. 当使用Python3-pygame时出现Typ ...
- Spring Boot:Thymeleaf 使用详解
Thymeleaf 介绍 简单说,Thymeleaf 是一个跟 Velocity.FreeMarker 类似的模板引擎,它可以完全替代 JSP .相较与其他的模板引擎,它有如下三个极吸引人的特点: 1 ...
- h5属性直接控制上传文件类型
和公司前端交互的时候发现我在选择上传文件的时候只能选择图片,其他类型,text,doc等等等等全部无法选择 仔细查看了下代码,发现归功于H5新增(??没查到资料,不确定是不是H5的)的input属性 ...