Go反射学习笔记

news/2025/1/24 2:05:02/

文章目录

    • 1、从类型对象中获取名称和种类
    • 2、使用反射获取结构体的成员类型
    • 3、从反射值对象中获取值的方法
    • 4、使用反射访问结构体的成员字段的值
    • 5、反射对象的空和有效性判断
    • 6、判定及获取元素的相关方法
    • 7、值修改的相关方法
    • 8、通过类型创建类型
    • 9、使用反射调用函数
    • 10、常用反射API
      • 从实例到Value
      • 从实例到Type
      • 从Type到Value
      • 从Value到Type
      • 从Value到实例
      • 从Value的指针到值
      • Type指针和值相互转换
      • Value值的可修改性

1、从类型对象中获取名称和种类

const (Zero int = 0
)
func main() {type stu struct{}typeofCat := reflect.TypeOf(stu{})fmt.Println(typeofCat.Name(), typeofCat.Kind()) //显示反射类型对象名称和种类typeOfA := reflect.TypeOf(Zero)fmt.Println(typeOfA.Name(), typeOfA.Kind())
}

2、使用反射获取结构体的成员类型

方法说明
Field(i int) StructField根据索引规返回索引对应的结构字段的信息,当值不是结构体或索引越界会发生宕机
NumField() int返回结构体成员字段数量,当类型不是结构体或索引越界时发生宕机
FieldByName(name string) (StructField bool)根据给定字段返回字符串对应的结构体字段的信息,没有找到时bool返回false,当类型不是结构体或索引越界时发生宕机
FieldByIndex(index[]int) StructField多层成员访问时,根据[]iny 提供的每个结构体的字段索引,返回字段的信息,没有找到返回零值。当类型不是结构体或索引越界时发生宕机
FieldByNameFunc(match func(string) bool)(StructField,bool)根据匹配函数匹配需要的字段,当值不是结构体或索引越界时发生宕机

3、从反射值对象中获取值的方法

方法名说明
Interface() interface{}将值以interface{}类型返回,可以通过类型断言为指定类型
Int() int64将值以int类型返回,所有有符号整数均可以此方式返回
Uint() uint64将值以uint类型返回,所有无符号整数均可以此方式返回
Float() float64将值以双精度类型返回,所有浮点数(float32,float64)均可以此方式返回
Bool() bool将值以bool类型返回
Bytes() []bytes将值以字节数组[]bytes类型返回
String() string将值以字符串类型返回
func main() {var m int = 2021valueOfA := reflect.ValueOf(m)var getA int = valueOfA.Interface().(int)var getA2 int = int(valueOfA.Int())fmt.Println(getA, getA2)
}

4、使用反射访问结构体的成员字段的值

方法说明
Field(i int) Value根据索引对应的结构体成员字段的反射对象,当值不是结构体或索引越界时发生宕机
NumField() int返回给结构体成员字段数量 ,当值不是结构体或索引越界时发生宕机
FieldByName(name string) Value根据给定字符串返回字符串对应的结构体字段,没有找到时返回零值,当值不是结构体或索引越界时发生宕机
FieldByIndex(index []int) Value多层成员返回时,根据[]int提供的每个结构体的字段索引,返回字段的值,没有找到时返回零值,当值不是结构体或索引越界时发生宕机
FieldByNameFunc(match func(string) bool) value根据匹配函数匹配需要的字段,找到时返回零值,当值不是结构体或索引越界时发生宕机
type stu struct {a intb stringfloat32boolnext *stu
}func main() {d := reflect.ValueOf(stu{next: &stu{},})fmt.Println("numField", d.NumField())floatField := d.Field(2)fmt.Println("floatField", floatField.Type())//根据名称查找字段fmt.Println("FieldsByName().Type", d.FieldByName("b").Type())fmt.Println("FieldByIndex()", d.FieldByIndex([]int{4, 0}).Type())
}

5、反射对象的空和有效性判断

| 方法 | 说明 |
| IsNil() bool | 返回值是否为nil,如果值类型不是通道(channel)、函数、接口、map、指针切片,类似于语言层的v==nil操作|
| IsValid() bool | 判断值是否有效。当值本身非法时,返回false,如reflect Value不包含任何值,值为nil等|

func main() {var a *intfmt.Println("var a *int:", reflect.ValueOf(a).IsNil())fmt.Println("nil:", reflect.ValueOf(nil).IsValid())fmt.Println("*int nil:", reflect.ValueOf((*int)(nil)).Elem().IsValid())s := struct{}{}fmt.Println("struct:", reflect.ValueOf(s).FieldByName("").IsValid())fmt.Println("并不存在的结构体方法:", reflect.ValueOf(s).MethodByName("").IsValid())m := map[int]int{}fmt.Println("不存在的键:", reflect.ValueOf(m).MapIndex(reflect.ValueOf(3)).IsValid())}

6、判定及获取元素的相关方法

方法名说明
Elem() Value取值指向的元素值,类似于语言层* 操作,当值类型不是指针或接口时发生宕机,空指针时返回nil的Value
Addr() Value对寻址的值返回其地址,类似于语言层&操作,当值不可寻址时发生宕机
CanAddr() bool表示值是否可寻址
CanSet() bool返回值能否被修改,要求值可寻址且是导出的字段

7、值修改的相关方法

Set(x Value)将值设置为传入反转值对象的值
SetUint(x uint64)使用uint64设置值,当值的类型不是uint,uint8,uint16,uint32,uint64会发生宕机
SetInt(x int64)比上面少了u
SetFloat(x float64)使用float54设置值,当值的类型不是float32,float64发生宕机
SetBool(x bool)使用bool设置值,当值的类型不是bool时发生宕机
SetBytes(x []byte)设置字节数组[] bytes值,当值的类型不是[]byte 会发生宕机
SetString(x string)设置字符串值.当值的类型不是string时会发生宕机
  • 可被寻址
  • 可被导出
func main() {a := 1024valueOfA := reflect.ValueOf(&a)valeOfEl := valueOfA.Elem()valeOfEl.SetInt(100)fmt.Println(a)}
func main() {type Dog struct {LegCount int}valueOfDog := reflect.ValueOf(&Dog{})valueOfDog = valueOfDog.Elem()vLegCount := valueOfDog.FieldByName("LegCount")vLegCount.SetInt(3)fmt.Println(vLegCount.Int())
}

8、通过类型创建类型

创建了新的类型

func main() {var a inttypeOfA := reflect.TypeOf(a)aIns := reflect.New(typeOfA)fmt.Println(aIns.Type(), aIns.Kind())
}

9、使用反射调用函数

func add(a, b int) int {return a + b
}
func main() {funcValue := reflect.ValueOf(add)paramList := []reflect.Value{reflect.ValueOf(10), reflect.ValueOf(20)}retList := funcValue.Call(paramList)fmt.Println(retList[0].Int())
}

10、常用反射API

从实例到Value

func ValueOf(i interface{}) Value

从实例到Type

func TypeOf (i interface{}) Type

从Type到Value

func NewAt (type Type,p unsafe.Pointer) Value

从Value到Type

func (v Value) Type() Type

从Value到实例

func (v Value) Interface() (i interface{})
func (v Value)  Bool() bool
func (v Value) Float() float64
func (v Value) Int() int64
func (v Value) Uint() uint64

从Value的指针到值

func (v Value) Elem() Value
func Indirect(v Value) Value

Type指针和值相互转换

t.Elem() Type //指针类型Type到值类型Type
func PtrTo(t Type) Type

Value值的可修改性

func (v Value) CanSet() bool
func (v Value) Set(x Value) 

http://www.ppmy.cn/news/1565650.html

相关文章

基于RK3576/RK3588+FPGA+AI深度学习的轨道异物检测技术研究

随着高速飞车技术的快速发展,轨道异物入侵已经成为影响列车安全行驶的重 要因素,急需对轨道异物快速识别,保证列车运行安全。传统的轨道异物检测存在 着检测结果不够准确和检测效率低下等问题,本文在综合分析国内外铁轨异物侵入 研…

【Python】笔试面试题之生成器、闭包、字典

文章目录 一、生成器是什么1. 最简单的生成器2. 在函数中使用yield关键字 二、闭包是什么?怎么理解?1. 案例12. 案例2:实现项目的日志处理3. 案例3:装饰器就是一种闭包4. 总结 三、Python中字典的底层是怎么实现的1. 相关概念2. P…

金融波动率的多模型建模研究:GARCH族与HAR模型的Python实现与对比分析

金融资产波动率建模在现代金融工程中具有重要地位,其应用涵盖风险管理、衍生品定价和投资组合优化等核心领域。本文着重探讨三种主流波动率建模方法:广义自回归条件异方差模型(GARCH)、Glosten-Jagannathan-Runkle-GARCH模型(GJR-GARCH)以及异质自回归模…

docker启动服务占用172.18网段怎么改成其他网段?和网桥有关吗?或者怎么改docker-compose启动用的yml文件

要修改 Docker 服务使用的网段(如从 172.18 改为其他网段),可以通过以下步骤实现: 1. 修改 Docker 默认网桥的网段 Docker 默认使用 docker0 网桥,其网段通常为 172.17.0.0/16。你可以通过修改 Docker 的配置文件来更改默认网段。 修改 Docker 配置文件 编辑 Docker 的…

初始JavaEE篇 —— 快速上手 SpringBoot

找往期文章包括但不限于本期文章中不懂的知识点: 个人主页:我要学编程程(ಥ_ಥ)-CSDN博客 所属专栏:JavaEE 目录 SpringBoot 相关介绍与解惑 SpringBoot 项目的创建 通过 官方提供的网页 来创建 通过 IDEA 来创建 SpringBoot 项目的介…

深度学习:大模型Decoding+MindSpore NLP分布式推理详解

大模型推理流程 1. 用户输入提示词(Prompt) 假设用户输入为:“从前,有一只小猫,它喜欢……” 我们的目标是让模型生成一段完整的故事。 2. 模型处理用户输入 2.1 分词:输入提示被分词为模型可以理解的…

MAC 地址转换为标准大写格式

// ConvertToStandardMac 将 MAC 地址转换为标准格式,确保每个字节都是两位,并且字母是大写的 func ConvertToStandardMac(mac string) (string, error) { // 分割 MAC 地址的每一部分 parts : strings.Split(mac, ":") // 确保每部分是两…

基于SpringBoot和PostGIS的各国及所属机场信息检索及可视化实现

目录 前言 一、空间数据简介 1、全球国家信息表 2、机场信息表 3、国家机场检索实现 二、SpringBoot后台实现 1、模型层实现 2、控制层实现 三、WebGIS可视化实现 1、Leaflet界面实现 2、国家及其机场可视化成果 3、全球机场数量排行榜 四、总结 前言 新春佳节即将…