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 ...
随机推荐
- 在阿里云开源镜像站中下载centOS7
镜像的选择 第一步.下载镜像 阿里云开源镜像站:http://mirrors.aliyun.com/ 选择centos进入 如下图: 如下图:选择centos7 再选择isos(镜像目录) 继续下一步 ...
- [大数据面试题]storm核心知识点
1.storm基本架构 storm的主从分别为Nimbus.Supervisor,工作进程为Worker. 2.计算模型 Storm的计算模型分为Spout和Bolt,Spout作为管口.Bolt作为 ...
- 【转载】阻塞队列之三:SynchronousQueue同步队列 阻塞算法的3种实现
一.SynchronousQueue简介 Java 6的并发编程包中的SynchronousQueue是一个没有数据缓冲的BlockingQueue,生产者线程对其的插入操作put必须等待消费者的移除 ...
- 前端使用JS-SDK上传图片(文件)到七牛
Qiniu-JavaScript-SDK (下文简称为 JS-SDK)适用于 :IE11.Edge.Chrome.Firefox.Safari 等浏览器,基于七牛云存储官方 API 构建,其中上传功能 ...
- javascript高级程序设计第3版——第6章 面向对象的程序设计
第六章——面向对象的程序设计 这一章主要讲述了:面向对象的语言由于没有类/接口情况下工作的几种模式以及面向对象语言的继承: 模式:工厂模式,构造函数模式,原型模式 继承:原型式继承,寄生式继承,以及寄 ...
- angular6 safe url pipe
safe-url.pipe.ts import { Pipe, PipeTransform } from '@angular/core'; import { DomSanitizer } from ' ...
- 【转】10分钟就能学会的.NET Core配置
.NET Core为我们提供了一套用于配置的API,它为程序提供了运行时从文件.命令行参数.环境变量等读取配置的方法.配置都是键值对的形式,并且支持嵌套,.NET Core还内建了从配置反序列化为PO ...
- WebService调用SSAS教程
WebService调用SSAS教程 一.创建SSAS项目 使用SQL Server Business Intelligence Development Studio新建Analysis Servic ...
- Win10优化:这8个操作简单的小方法让你的Win10系统更加流畅
目前,市场上比较流行的主流电脑系统无非就是win7和win10这两个,这两个也是比较稳定的.但是自从微软发布将于2020年停止对win7支持后,很多小伙伴也表示无奈之下得升win10了啊. win10 ...
- python输入字符串
#!/usr/bin/env python#ecoding=utf-8'''Created on 2017年11月2日题目:利用递归函数调用方式,将所输入的5个字符,以相反顺序打印出来. @autho ...