当前位置: 首页 > article >正文

go反射深入学习

Go 语言中的反射详解
反射是 Go 语言中的一个强大功能,可以在运行时动态获取和操作类型和值。了解反射有助于构建更灵活和通用的代码。本篇博客主要介绍 Go 语言反射的三大基本定律及其相关用法。

  1. 反射第一定律:反射可以将 interface 类型变量转换成反射对象
    基本用法
    通过 reflect.TypeOf() 和 reflect.ValueOf(),可以从 interface 类型变量中获取反射对象的类型和值。例如:

go
复制代码
package main

import (
“fmt”
“reflect”
)

func main() {
var x float64 = 3.4
t := reflect.TypeOf(x) // t 是 reflect.Type
fmt.Println(“type:”, t)

v := reflect.ValueOf(x) // v 是 reflect.Value
fmt.Println("value:", v)

}
输出:

go
复制代码
type: float64
value: 3.4
解释
reflect.TypeOf() 和 reflect.ValueOf() 都接受 interface{} 类型参数,表明 x 在调用时会被转换为 interface。通过 reflect.Value 和 reflect.Type,我们可以在运行时获取变量的具体信息。

  1. 反射第二定律:反射对象可以还原为 interface 对象
    反射与 interface 之间是可以相互转换的。以下代码展示如何从反射对象还原为具体的 interface 对象:

go
复制代码
package main

import (
“fmt”
“reflect”
)

func main() {
var x float64 = 3.4

v := reflect.ValueOf(x) // v 是 reflect.Value

var y float64 = v.Interface().(float64)
fmt.Println("value:", y)

}
输出:

makefile
复制代码
value: 3.4
解释
我们将对象 x 转换成了反射对象 v,然后通过 v.Interface() 将 v 转回 interface{},最后用类型断言将其还原为 float64。这种方式展示了反射对象与具体类型对象之间的互操作能力。

  1. 反射第三定律:反射对象可修改,Value 值必须是可设置的
    为了说明反射如何修改值,我们先看一个失败的例子:

go
复制代码
package main

import (
“reflect”
)

func main() {
var x float64 = 3.4
v := reflect.ValueOf(x)
v.SetFloat(7.1) // Error: will panic.
}
输出:

vbnet
复制代码
panic: reflect: reflect.Value.SetFloat using unaddressable value
解释
错误的原因是 v 是不可修改的。传递给 reflect.ValueOf() 的是 x 的值,而不是 x 的地址。由于 Go 语言的函数传参机制是值传递,反射修改 v 的值是无效的。

正确的修改方式
我们需要传递 x 的地址,并使用 Elem() 获取指针指向的值:

go
复制代码
package main

import (
“fmt”
“reflect”
)

func main() {
var x float64 = 3.4
v := reflect.ValueOf(&x) // 传递 x 的地址
v.Elem().SetFloat(7.1) // 修改指针指向的值
fmt.Println(“x :”, v.Elem().Interface())
}
输出:

yaml
复制代码
x : 7.1
解释
reflect.ValueOf(&x) 将 x 的地址传递给 reflect.Value,这使得我们能够通过反射修改 x 的值。v.Elem() 用于获取指针指向的实际值,从而允许修改。

总结
反射第一定律:反射可以将 interface 类型变量转换成反射对象,利用 reflect.TypeOf() 和 reflect.ValueOf() 获取类型和值。
反射第二定律:反射对象可以还原为 interface 对象,通过 Interface() 方法实现。
反射第三定律:要修改反射对象,其值必须是可设置的;通常需要使用指针来获取和修改值。
反射是 Go 语言中构建动态和灵活代码的关键工具,但需要注意性能开销和可能引入的复杂性。了解反射的基本定律和用法,可以更好地掌握和使用 Go 的强大特性。


http://www.kler.cn/a/395670.html

相关文章:

  • LeetCode654.最大二叉树
  • <AI 学习> 下载 Stable Diffusions via Windows OS
  • 医院信息化与智能化系统(21)
  • 速盾:如何有效防止服务器遭受攻击?
  • 统信UOS开发接口DTK
  • 【Java语言】String类
  • Linux运维工程师推荐学习的开发语言
  • 【C++初阶】C++入门
  • CentOS 7中查找已安装JDK路径的方法
  • 探索 HTML 和 CSS 实现的蜡烛火焰
  • 【5.线性表-链式表示-王道课后算法题】
  • wordcloud库基本介绍
  • hbase未来的发展趋势
  • linux配置nginx
  • 【Homework】【6】Learning resources for DQ Robotics in MATLAB
  • Android Framework AMS面试题及参考答案
  • 借助Excel实现Word表格快速排序
  • ssh登陆服务器后支持Tab键命令补全
  • Python中的HTTP协议
  • Linux kernel 堆溢出利用方法(二)
  • 2024年11月15日Github流行趋势
  • GOLANG笔记第四周
  • 【回溯法】——单词搜索
  • Oracle 单机及 RAC 环境 归档模式及路径修改
  • Django 2024全栈开发指南(三):数据库模型与ORM操作(上篇)
  • 搜索,CF 1666L - Labyrinth