2025年3月28日 星期五 甲辰(龙)年 月廿七 设为首页 加入收藏
rss
您当前的位置:首页 > 计算机 > 编程开发 > Go语言

Golang 反射(Reflect)

时间:12-14来源:作者:点击数:5

先推荐一篇讲reflect讲的不错的文章: https://blog.golang.org/laws-of-reflection

反射可以让我们在运行时检查变量的状态。golang 提供了反射的包 reflect

1.基本操作 reflect.TypeOf & reflect.ValueOf

reflect.TypeOf 返回 reflect.Type 类型:

  • package main
  • import (
  • "fmt"
  • "reflect"
  • )
  • func main() {
  • var x float64 = 3.4
  • fmt.Println("type:", reflect.TypeOf(x)) // 输出:type: float64
  • }

reflect.ValueOf 返回 reflect.Value 类型,该类型下有很多方法可以使用:

  • var x float64 = 3.4
  • v := reflect.ValueOf(x)
  • fmt.Println("type:", v.Type())
  • fmt.Println("kind is float64:", v.Kind() == reflect.Float64)
  • fmt.Println("value:", v.Float())

输出为:

  • type: float64
  • kind is float64: true
  • value: 3.4

2.将 reflect.Value 转换为 interface{}

通过上文的方法得到 reflect.Value 类型之后,我们还可以将该类型再转换回 interface{} 类型:

  • var x float64 = 3.4
  • v := reflect.ValueOf(x)
  • fmt.Println(v.Interface())

3.修改 reflect.Value

reflect.Value 类型还有对应的修改方法,但是,下面的写法会报 panic:

  • var x float64 = 3.4
  • v := reflect.ValueOf(x)
  • v.SetFloat(7.1) // Error: will panic.

其实,我们可以通过 CanSet() 方法来判断是否能修改:

  • var x float64 = 3.4
  • v := reflect.ValueOf(x)
  • fmt.Println("settability of v:", v.CanSet()) // false

那么这里为什么不能修改呢?其实就和函数传值类似,当我们进行值传递而不是引用传递时,就算在函数内部修改了变量,对外部调用者来说也是不可见的,这里的 reflect.Value 也是同理,它创建了对一个原始值的拷贝而不是引用,所以直接修改 reflect.Value 并不能对原始值产生影响。

正确的修改方法是使用引用创建 reflect.Value :

  • var x float64 = 3.4
  • p := reflect.ValueOf(&x) // Note: take the address of x.
  • fmt.Println("type of p:", p.Type()) // *float64
  • fmt.Println("settability of p:", p.CanSet()) // false
  • v := p.Elem()
  • fmt.Println("settability of v:", v.CanSet()) // true
  • v.SetFloat(7.1) // 还有SetString, SetInt...
  • fmt.Println(x) // x已经被修改为7.1了
方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门
本栏推荐