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 ...
随机推荐
- Phpstorm-远程连接服务器实时编辑代码
一,配置远程服务器FTP 1.打开Phpstorm >>> 选择 2.选择 3.输入项目名称(此项目名称不会同步到服务器,只是在本地电脑上的项目名称) 4.将编辑器设置为实时自动同步 ...
- python爬取某站磁力链
不同磁力链网站网页内容都不同,需要定制 1,并发爬取 并发爬取后,好像一会就被封了 import requests from lxml import etree import re from conc ...
- postgresql 空间函数 随笔
1. ST_Buffer(geometry, double, [integer])buffer操作一个很有用函数,这个函数的第一个参数是要操作的空间几何数据,第二个参数长度(距离),第三个参数为一个整 ...
- HBase表数据的转移之使用自定义MapReduce
目标:将fruit表中的一部分数据,通过MR迁入到fruit_mr表中 Step1.构建ReadFruitMapper类,用于读取fruit表中的数据 package com.z.hbase_mr; ...
- python内置函数详细描述与实例演示
python有许多内置函数,列出表格如下 内置函数 abs() delattr() hash() memoryview() set() all() dict() help() min() setatt ...
- Markdown的基本语法记录
1.标题 示例代码: # 标题1 ## 标题2 ### 标题3 #### 标题4 ##### ... 效果: 标题1 标题2 标题3 标题4 ... 注:# 后面应保持空格 2. 分级标题 示例代码: ...
- Django中ORM介绍和字段及字段参数
Object Relational Mapping(ORM) 1 ORM介绍 1.1 ORM概念 对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对 ...
- 举例说明$POST 、$HTTP_RAW_POST_DATA、php://input三者之间的区别
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 《BUG创造队》第一次作业:团队亮相
项目 内容 这个作业属于哪个课程 2016级软件工程 这个作业的要求在哪里 第五次实验 团队名称 BUG创造队 作业学习目标 通过本次项目了解并熟悉团队开发的过程 关于我们 -我们的队名:BUG创造队 ...
- 简单的jQuery hide()方法演示
<!DOCTYPE html><html><head><meta charset="utf-8"> <title>jQu ...