9.1 Go 反射

反射:可以在运行时,动态获取变量的信息,比如变量的类型,类别

1.对于结构体变量,还可以获取到结构体的字段,方法

2.实现这个功能的是 reflect包

reflect.TypeOf(),获取变量的类型,返回reflect.Type类型
reflect.ValueOf(),获取变量的值,返回reflect.Value类型
reflect.Value.Kind(),获取变量的类别,返回一个常量
reflect.Value.Interface(),转换成interface{}类型

使用反射场景,json序列化

package main

import (
"encoding/json"
"fmt"
) type Student struct {
Name string `json:"学生名"`
Age int `json:"学生年纪"`
Class string `json:"班级"`
} func main() {
stu := Student{
"尼古拉斯赵四",
18,
"舞王班",
}
data, err := json.Marshal(stu)
if err != nil {
fmt.Println("序列化出错", err)
}
fmt.Println("json序列化结果:", string(data))
}

反射获取基本类型

package main

import (
"fmt"
"reflect"
) func main() {
var num int64 = 12345
fmt.Println("num类型", reflect.TypeOf(num))
//获取变量的值
resNum := reflect.ValueOf(num)
fmt.Printf("类型:%T 值:%v\n", resNum, resNum)
fmt.Printf("resNum值:%v\n", resNum)
fmt.Printf("resNum类型:%v\n", resNum.Type())
fmt.Printf("resNum种类:%v\n", resNum.Kind())
fmt.Printf("resNum确认值:%v\n", resNum.Int())
}

反射获取结构体

package main

import (
"fmt"
"reflect"
) //学生结构体
type Student struct {
Name string
Age int
Score float32
} //函数接收类型是接口,可以接收任何类型
func test(b interface{}) {
t := reflect.TypeOf(b)
fmt.Println("参数类型:", t) v := reflect.ValueOf(b)
fmt.Println("参数值:", v) k := v.Kind()
fmt.Println("参数种类:", k)
//转化为接口返回
iv := v.Interface()
fmt.Printf("类型:%T 值:%v\n", iv, iv)
//类型断言,如果这个接口是student类型
stu, ok := iv.(Student)
if ok {
fmt.Printf("结构体值:%v 类型:%T\n", stu, stu)
}
} func main() {
var a Student = Student{
Name: "周星驰",
Age: 18,
Score: 99,
}
//传入结构体
test(a)
}

反射elem获取指针指向的变量

package main

import (
"fmt"
"reflect"
) //fv.Elem()用来获取指针指向的变量
func testInt(b interface{}) {
//获取b的类型
val := reflect.ValueOf(b)
fmt.Printf("参数b的类型是:%T 值是:%v\n", val, val)
fmt.Printf("val.Elem()获取到变量的类型:%T 值:%v\n", val.Elem(), val.Elem())
//修改val的值
val.Elem().SetInt(100)
//返回 一个int值类型
c := val.Elem().Int()
fmt.Printf("类型:%T 值是:%d\n", c, c)
} func main() {
var b int = 1
b = 200
testInt(&b)
fmt.Println("b的值:", b)
}

理解reflect.Value.Elem()

package main

import (
"fmt"
"reflect"
) func main() {
var num int = 100
//返回变量的值,传入地址,那就是内存地址的值
fn := reflect.ValueOf(&num)
//修改指针指向的值,也就是修改num的值
fn.Elem().SetInt(222)
fmt.Printf("此时num的值:%d\n", num) //以上操作,等同于
var num2 = 111
var b *int = &num2
*b = 333
fmt.Printf("b的类型:%T\n", b)
fmt.Println(num2)
}

9.1 Go 反射的更多相关文章

  1. 隐私泄露杀手锏 —— Flash 权限反射

    [简版:http://weibo.com/p/1001603881940380956046] 前言 一直以为该风险早已被重视,但最近无意中发现,仍有不少网站存在该缺陷,其中不乏一些常用的邮箱.社交网站 ...

  2. Java学习之反射机制及应用场景

    前言: 最近公司正在进行业务组件化进程,其中的路由实现用到了Java的反射机制,既然用到了就想着好好学习总结一下,其实无论是之前的EventBus 2.x版本还是Retrofit.早期的View注解框 ...

  3. 关于 CSS 反射倒影的研究思考

    原文地址:https://css-tricks.com/state-css-reflections 译者:nzbin 友情提示:由于演示 demo 的兼容性,推荐火狐浏览.该文章篇幅较长,内容庞杂,有 ...

  4. 编写高质量代码:改善Java程序的151个建议(第7章:泛型和反射___建议106~109)

    建议106:动态代理可以使代理模式更加灵活 Java的反射框架提供了动态代理(Dynamic Proxy)机制,允许在运行期对目标类生成代理,避免重复开发.我们知道一个静态代理是通过主题角色(Prox ...

  5. 运用Mono.Cecil 反射读取.NET程序集元数据

    CLR自带的反射机智和API可以很轻松的读取.NET程序集信息,但是不能对程序集进行修改.CLR提供的是只读的API,但是开源项目Mono.Cecil不仅仅可以读取.NET程序集的元数据,还可以进行修 ...

  6. .NET面试题系列[6] - 反射

    反射 - 定义,实例与优化 在面试中,通常会考察反射的定义(操作元数据),可以用反射做什么(获得程序集及其各个部件),反射有什么使用场景(ORM,序列化,反序列化,值类型比较等).如果答得好,还可能会 ...

  7. .NET基础拾遗(4)委托、事件、反射与特性

    Index : (1)类型语法.内存管理和垃圾回收基础 (2)面向对象的实现和异常的处理基础 (3)字符串.集合与流 (4)委托.事件.反射与特性 (5)多线程开发基础 (6)ADO.NET与数据库开 ...

  8. C++的性能C#的产能?! - .Net Native 系列五:.Net Native与反射

    此系列系小九的学堂原创翻译,翻译自微软官方开发向导,一共分为六个主题.本文是第五个主题:.Net Native与反射. 向导文链接:<C++的性能C#的产能?! - .Net Native 系列 ...

  9. [源码]Literacy 快速反射读写对象属性,字段

    Literacy 说明 Literacy使用IL指令生成方法委托,性能方面,在调用次数达到一定量的时候比反射高很多 当然,用IL指令生成一个方法也是有时间消耗的,所以在只使用一次或少数几次的情况,不但 ...

  10. SI与EMI(一) - 反射是怎样影响EMI

    Mark为期两天的EMC培训中大概分成四个时间差不多的部分,简单来说分别是SI.PI.回流.屏蔽.而在信号完整性的书籍中,也会把信号完整性分为:1.信号自身传输的问题(反射,损耗):2.信号与信号之间 ...

随机推荐

  1. thinkphp5.1+ 使用 Redis 缓存

    修改 config/cache.php 将其配置成多个缓存类型,示例 <?php // +---------------------------------------------------- ...

  2. Metasploit渗透测试环境搭建

    渗透测试实验环境搭建 下载虚拟机镜像 5个虚拟机镜像,其中Linux攻击机我选择用最新的kali Linux镜像,其余的均使用本书配套的镜像. 网络环境配置 VMware虚拟网络编辑器配置: 将VMn ...

  3. linux下报错:error while loading shared libraries

    linux执行bin程序报: error while loading shared libraries:libncurses.so.5: cannot open shared object file: ...

  4. P1466 集合 Subset Sums 搜索+递推+背包三种做法

    题目描述 对于从1到N (1 <= N <= 39) 的连续整数集合,能划分成两个子集合,且保证每个集合的数字和是相等的.举个例子,如果N=3,对于{1,2,3}能划分成两个子集合,每个子 ...

  5. The 2019 Asia Nanchang First Round Online Programming Contest B Fire-Fighting Hero(阅读理解)

    This is an era of team success, but also an era of heroes. Throughout the ages, there have been nume ...

  6. Jenkins 构建 Jmeter 项目

    1.启动 Jenkins(windows 版本) 2.新建自由风格的项目 定时任务 构建操作 安装 HTML Publisher 插件 构建后操作 最后保存构建,查看报告

  7. JavaScript从入门到精通(转)

    JavaScript从入门到精通 转自: https://github.com/Eished/JavaScript_notes 视频连接:https://www.bilibili.com/video/ ...

  8. Java 常用API(一)

    目录 Java 常用API(一) 1. Scanner类 引用类型的一般使用步骤 Scanner的使用步骤 例题 2. 匿名对象 概述 匿名对象作为方法的参数 匿名对象作为方法的返回值 3. Rand ...

  9. Go语言入门教程系列——函数、循环与分支

    本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是Golang专题的第四篇,这一篇文章将会介绍golang当中的函数.循环以及选择判断的具体用法. 函数 在之前的文章当中其实我们已经接 ...

  10. LeetCode--LinkedList--141.Linked List Cycle(Easy)

    141. Linked List Cycle(Easy)2019.7.10 题目地址https://leetcode.com/problems/linked-list-cycle/ Given a l ...