Go基础之--反射
反射:可以在运行时动态获取变量的相关信息
反射需要导入reflect
反射中重要函数的演示
反射有几下几个重要的函数:
reflect.TypeOf :获取变量的类型,返回reflect.Type类型
reflect.ValueOf:获取变量的值,返回reflect.Value类型
reflect.Value.Kind:获取变量的类别,返回一个常量
reflect.Value.Interface():转换成interface{}类型
通过一个小例子来理解:
- package main
- import (
- "reflect"
- "fmt"
- )
- type Student struct{
- Name string
- Age int
- }
- func (s*Student) SetName(name string){
- s.Name="coders"
- }
- func (s*Student)SetAge(age int){
- s.Age = 23
- }
- func getTypeInfo(a interface{}){
- // 用于获取一个数据的数据类型
- typeInfo := reflect.TypeOf(a)
- kind := typeInfo.Kind()
- fmt.Println("kind of a :",kind)
- num := typeInfo.NumMethod() //获取当前数据有多少个方法
- fmt.Println("method num:",num)
- method,ok:=typeInfo.MethodByName("SetName") //获取是否有某个方法
- if !ok{
- fmt.Println("not have method SetName")
- }else{
- fmt.Println(method)
- }
- }
- func getAllMethod(a interface{}){
- // 用于获取变量下的所有方法
- typeInfo := reflect.TypeOf(a)
- num := typeInfo.NumMethod()
- for i:=0;i<num;i++ {
- method:= typeInfo.Method(i)
- fmt.Println(method)
- }
- }
- func testGetAllMethod() {
- var stu Student
- getAllMethod(&stu)
- }
- func testGetTypeInfo(){
- var i int
- getTypeInfo(i) //获取的结果就是int
- var stu Student
- getTypeInfo(&stu) //获取的结果就是struct
- getAllMethod(&stu)
- var s []int
- getTypeInfo(s) //获取的结果就是slice
- var a [5]int
- getTypeInfo(a) //获取的结果就是array
- }
- func testGetValueInfo(){
- var i = 100
- valueInfo := reflect.ValueOf(i)
- tmp := valueInfo.Interface() //转换成interface类型
- val := tmp.(int) //这里我是知道是int所以直接转换了
- fmt.Println("val:",val) //这里获取的还是100
- fmt.Println("val of valueInfo:",valueInfo.Int()) // 这里打印的也是100
- fmt.Println("type:",valueInfo.Type())
- fmt.Println("kind:",valueInfo.Kind())
- }
- func main(){
- testGetTypeInfo()
- testGetAllMethod()
- testGetValueInfo()
- }
上面这个例子中演示了reflect.Value.Kind()可以返回int,struct,slice,array,当然这里可以返回的类型还有很多如下:
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
获取变量的值
reflect.ValueOf(x).Float()
reflect.ValueOf(x).Int()
reflect.ValueOf(x).String()
reflect.ValueOf(x).Bool()
这个功能在上面的代码中也有演示
通过反射来改变变量的值
reflect.Value.SetXX相关方法,如:
reflect.Value.SetFloat():设置浮点数
reflect.Value.SetInt():设置整数
reflect.Value.SetString():设置字符串
通过下面一个简单的例子来演示:
- package main
- import (
- "reflect"
- "fmt"
- )
- func main() {
- var a float64
- fmt.Println(a)
- fv := reflect.ValueOf(a)
- fv.SetFloat(3.14)
- fmt.Println(a)
- }
上面这段代码会提示如下错误:
这里需要知道的是我们的变量a是一个值类型的变量,我们通过reflect.valueOf传入的时候其实是传入的变量的拷贝,所以我们如果通过SetFloat给变量设置值的时候其实并不会生效,go这里已经替我考虑到了,所以给我们提示了上面这个错误信息,那是不是我们在reflect.Value的传入地址就可以了呢,我把上述代码中更改为:reflect.Value(&a),当我们运行后发现还是报了和上面相同的错误,这是为什么呢?
我们应该还记得如果是一个指针的时候我们赋值的时候是需要在指针的左边写个*符号,但是这是在反射里面我们怎么写星号,所以go在这里提供给我们另外一个方法,当我们通过调用SetFloat的时候用:
fv.Elem().SetFloat(3.14)这种方式调用就ok了,完整的正确代码为:
- package main
- import (
- "reflect"
- "fmt"
- )
- func main() {
- var a float64
- fmt.Println(a)
- fv := reflect.ValueOf(&a)
- fv.Elem().SetFloat(3.14)
- fmt.Println(a)
- }
反射操作结构体
reflect.Value.NumField():获取结构体中字段的个数
reflect.Value.Method(n).Call():调用结构体中的方法
- package main
- import (
- "reflect"
- "fmt"
- )
- type Student struct{
- Name string
- Age int
- Sex int
- }
- func (s *Student) Set(name string,age int,sex int){
- s.Name = name
- s.Age = age
- s.Sex = sex
- }
- func testStruct() {
- var stu *Student = &Student{}
- stu.Set("coder",23,1)
- valueInfo := reflect.ValueOf(stu)
- fieldNum := valueInfo.Elem().NumField()
- fmt.Println("filed num:",fieldNum) //这里返回的结果是3
- sexValueInfo := valueInfo.Elem().FieldByName("Sex")
- fmt.Println("sex=",sexValueInfo.Int())
- sexValueInfo.SetInt(0) //这里是更改值
- fmt.Println(stu)
- setMethod := valueInfo.MethodByName("Set") //获取Set方法
- var params []reflect.Value
- name := "tom"
- age := 18
- sex:=2
- params = append(params,reflect.ValueOf(name),reflect.ValueOf(age),reflect.ValueOf(sex))
- setMethod.Call(params) //调用Set方法
- fmt.Println(stu) //将最开始的值已经更改了
- }
- func main() {
- testStruct()
- }
Go基础之--反射的更多相关文章
- 黑马程序员:Java基础总结----反射
黑马程序员:Java基础总结 反射 ASP.Net+Android+IO开发 . .Net培训 .期待与您交流! 反射 反射的基石:Class类 Class类代表Java类,它的各个实例对象又分别 ...
- Go语言基础之反射
Go语言基础之反射 本文介绍了Go语言反射的意义和基本使用. 变量的内在机制 Go语言中的变量是分为两部分的: 类型信息:预先定义好的元信息. 值信息:程序运行过程中可动态变化的. 反射介绍 反射是指 ...
- Python 基础 三 反射
Python 基础 三 反射 今天我们先介绍一下反射这个概念,啥是反射?反射就是自己检测自己.在我们Python的面向对象中的反射是啥意思呢?就是通过字符串的形式操作对象相关的属性.python中的一 ...
- JAVA基础知识|反射
一.理解反射 1.1.基础概念 反射:在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意方法和属性:这种动态获取信息以及动态调用对象方法的功能称为ja ...
- GO学习-(17) Go语言基础之反射
Go语言基础之反射 本文介绍了Go语言反射的意义和基本使用. 变量的内在机制 Go语言中的变量是分为两部分的: 类型信息:预先定义好的元信息. 值信息:程序运行过程中可动态变化的. 反射介绍 反射是指 ...
- JAVA安全基础之反射
JAVA安全基础之反射 在JAVA安全中,反射是一个经常使用的技术,所以熟悉使用反射是非常必要的.下面就简单的讲下JAVA的反射的用法 什么是反射 每个类都有对应的Class类对象,该Class类对象 ...
- 黑马程序员_Java基础:反射机制(Reflection)总结
------- android培训.java培训.期待与您交流! ---------- 反射在java中有非常重大的意义,它是一种动态的相关机制,可以于运行时加载.探知.使用编译期间完全未知的clas ...
- C#基础|初探反射
什么是反射 我们编写的C#代码都可以编译成exe文件或dll文件.暂时先把他们叫做程序集吧,程序集中包含了很多信息.你写了一个类,类中会有字段,有属性,有方法,编译是会把这些信息保存在程序集中,暂时把 ...
- Java基础之一反射
反射是框架设计的灵魂 (使用的前提条件:必须先得到代表的字节码的Class,Class类用于表示.class文件(字节码)) 一.反射的概述 JAVA反射机制是在运行状态中,对于任意一个类,都能够 ...
- python基础(14)-反射&类的内置函数
反射 几个反射相关的函数可参考python基础(10)-匿名函数&内置函数中2.2.4反射相关 类的一些内置函数 __str__()&__repr__() 重写__str__()函数类 ...
随机推荐
- jvm内存模型-回收算法-和内存分配以及jdk、jre、jvm是什么关系(阿里,美团,京东面试题)
1.什么是jvm?(1)jvm是一种用于计算设备的规范,它是一个虚构出来的机器,是通过在实际的计算机上仿真模拟各种功能实现的.(2)jvm包含一套字节码指令集,一组寄存器,一个栈,一个垃圾回收堆和一个 ...
- [国嵌攻略][099][Linux内核配置与编译]
为什么要配置内核 基于硬件和软件的需求选出需要的功能,去掉不要的功能. 内核配置的方法 make config:基于文本交互的配置. make menuconfig:基于图形菜单的配置. make m ...
- TypeScript和Node模块解析策略
一般我们在模块化编码时,总会导入其它模块,通常我们使用如下语法: import { A } from './a'; // ES6语法 import { A } from 'a'; var A = re ...
- 最小生成树之Prim算法
描述 最近,小Hi很喜欢玩的一款游戏模拟城市开放出了新Mod,在这个Mod中,玩家可以拥有不止一个城市了! 但是,问题也接踵而来--小Hi现在手上拥有N座城市,且已知这N座城市中任意两座城市之间建造道 ...
- PHP headers_sent() 函数
PHP HTTP 函数 定义和用法 headers_sent() 函数检查 HTTP 标头是否已被发送以及在哪里被发送. 如果报头已发送,则返回 true,否则返回 false. 语法 headers ...
- navicat将多个表导出为一个sql文件
1.shift选中多个表 2右键选择--转储sql文件---结构和数据
- C语言第二次实验报告
1.实验题目 题1:11-7 找鞍点(20 分) 一个矩阵元素的"鞍点"是指该位置上的元素值在该行上最大.在该列上最小. 本题要求编写程序,求一个给定的n阶方阵的鞍点 题2: ...
- 关于JWPlayer播放器的一些测试学习
<!DOCTYPE html><html><head> <title>jwplayer播放器测试</title> <script ty ...
- struts2 从一个action跳转到另一个action的struts.xml文件的配置
解释: 想要用<result>跳转到另一个action,原来的配置代码是: <action name="insertDept" class="strut ...
- win7 使用anaconda安装tensorflow并且在jupyter notebook上启动
记录一下学习深度学习的小事情: 1.tensorflow 现在只支持windows 64位系统: 2.因为实验室的电脑比较老旧,Gpu配置低,所以选择安装的是tensorflow Cpu版本,对于学习 ...