Golang 反射(Reflect)

发布于 2022-02-05 12:55:28 字数 2176 浏览 854 评论 0

先推荐一篇讲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了

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

JSmiles

生命进入颠沛而奔忙的本质状态,并将以不断告别和相遇的陈旧方式继续下去。

0 文章
0 评论
84960 人气
更多

推荐作者

lorenzathorton8

文章 0 评论 0

Zero

文章 0 评论 0

萧瑟寒风

文章 0 评论 0

mylayout

文章 0 评论 0

tkewei

文章 0 评论 0

17818769742

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文