目录

  • 变量介绍
  • 反射介绍
  • 结构体反射
  • 反射总结以及应用场景

变量介绍

1、变量的内在机制

A. 类型信息,这部分是元信息,是预先定义好的
B. 值类型,这部分是程序运行过程中,动态改变的

var arr [10]int
arr[0] = 10
arr[1] = 20
arr[2] = 30
arr[3] = 40
arr[4] = 50 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())
}

  

const (
Invalid Kind = iota
Bool
Int
Int8
Int16
Int32
Int64
Uint
Uint8
Uint16
Uint32
Uint64
Uintptr
Float32
Float64
Complex64
Complex128
Array
Chan
Func
Interface
Map
Ptr
Slice
String
Struct
UnsafePointer
)

  

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())

  

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.NumMethod())
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"))
}

 

反射总结以及应用场景

1、反射总结

A.在运行时动态的获取一个变量的类型信息和值信息

2. 应用场景

A. 序列化和反序列化,比如json, protobuf等各种数据协议
B. 各种数据库的ORM, 比如gorm,sqlx等数据库中间件
C. 配置文件解析相关的库, 比如yaml、ini等

【原创】go语言学习(十八)反射详解的更多相关文章

  1. Go语言学习之6 反射详解

    1.反射: 定义: 反射就是程序能够在运行时检查变量和值,求出它们的类型.                   可以在运行时动态获取变量的相关信息                   Import ( ...

  2. Java数据持久层框架 MyBatis之API学习十(Logging详解)

    对于MyBatis的学习而言,最好去MyBatis的官方文档:http://www.mybatis.org/mybatis-3/zh/index.html 对于语言的学习而言,马上上手去编程,多多练习 ...

  3. Go语言学习之8 goroutine详解、定时器与单元测试

    主要内容: 1.Goroutine2. Chanel3. 单元测试 1. Goroutine Go 协程(Goroutine)(轻量级的线程,开线程没有数量限制).   (1)进程和线程 A. 进程是 ...

  4. Linux学习之用户配置文件详解(十四)

    Linux学习之用户配置文件详解 目录 用户信息文件/etc/password 影子文件/etc/shadow 组信息文件/etc/group 组密码文件/etc/gshadow 用户信息文件/etc ...

  5. Go语言学习笔记八: 数组

    Go语言学习笔记八: 数组 数组地球人都知道.所以只说说Go语言的特殊(奇葩)写法. 我一直在想一个人参与了两种语言的设计,但是最后两种语言的语法差异这么大.这是自己否定自己么,为什么不与之前统一一下 ...

  6. [深入学习Web安全](5)详解MySQL注射

    [深入学习Web安全](5)详解MySQL注射 0x00 目录 0x00 目录 0x01 MySQL注射的简单介绍 0x02 对于information_schema库的研究 0x03 注射第一步—— ...

  7. Shell学习之Bash变量详解(二)

    Shell学习之Bash变量详解 目录 Bash变量 Bash变量注意点 用户自定义变量 环境变量 位置参数变量 预定义变量 Bash变量 用户自定义变量:在Bash中由用户定义的变量. 环境变量:这 ...

  8. Asp.Net MVC学习总结之过滤器详解(转载)

    来源:http://www.php.cn/csharp-article-359736.html   一.过滤器简介 1.1.理解什么是过滤器 1.过滤器(Filters)就是向请求处理管道中注入额外的 ...

  9. C#反射の反射详解

    C#反射の反射详解(点击跳转)C#反射の反射接口(点击跳转)C#反射反射泛型接口(点击跳转)C#反射の一个泛型反射实现的网络请求框架(点击跳转) 一.什么是反射 反射(Reflection):这是.N ...

  10. [转载]springmvc学习之@ModelAttribute运用详解

    spring学习之@ModelAttribute运用详解 链接

随机推荐

  1. 设计模式--装饰者模式(io流中使用的模式)

    重点: 1.动态扩展对象,替换之前需要继承才能实现的功能. 2.具体工作的,仍然是被包装的对象,(有点锦上添花的意思,顾名思义仅仅起到装饰的作用,主体不变). 对比继承: 1.减少类的数量. 如果使用 ...

  2. 织梦安全防护:禁止uploads、data、templets执行脚本

    下面介绍下如何针对uploads.data.templets做PHP脚本限制:对uploads.data.templets 三个目录做执行php脚本限制,就算被上传了木马文件到这些文件夹,也是无法运行 ...

  3. VK Cup 2017 - Round 1 (CDE)

    771C Bear and Tree Jumps 大意: 给定树,每步能走到距离不超过$k$的任意点,记$f(s,t)$为$s$到$t$的最少步数,求$\sum\limits_{s<t}f(s, ...

  4. Python——pip的安装与使用

    pip 是 Python 包管理工具,该工具提供了对Python 包的查找.下载.安装.卸载的功能.目前如果你在 python.org 下载最新版本的安装包,则是已经自带了该工具.Python 2.7 ...

  5. Django配置websocket请求接口

    1.settings.py INSTALLED_APPS = [ '...', 'channels', '...', ] ASGI_APPLICATION = 'server.routing.appl ...

  6. Fortify漏洞之XML External Entity Injection(XML实体注入)

    继续对Fortify的漏洞进行总结,本篇主要针对  XML External Entity Injection(XML实体注入) 的漏洞进行总结,如下: 1.1.产生原因: XML External ...

  7. EWA不能及时通过邮件接收

    1. 确保EWA已经配置成功.可以通过SW_workcenter查看 2.确保EWA的邮箱设置成功 3. 检查EWAreport产生的时间 卫星系统:SDCCN 在tab"done" ...

  8. Linux 知识

    linux下如何查看某软件是否已安装 因为linux安装软件的方式比较多,所以没有一个通用的办法能查到某些软件是否安装了.总结起来就是这样几类: 1.rpm包安装的,可以用rpm -qa看到,如果要查 ...

  9. Opencv---零碎记录

    OpenCV支持CPU和OpenCL推断,但OpenCL只支持Intel自家GPU,Satya设置了CPU推断模式(cv.dnn.DNN_TARGET_CPU) https://docs.opencv ...

  10. python3 excel基本操作及格式设置

    #encoding=utf-8 ''' excel基本操作整理 ''' #openpyxl 版本2.5.4 from openpyxl import * import datetime as dt f ...