写点什么

Golang 反射

用户头像
escray
关注
发布于: 2021 年 04 月 24 日
Golang 反射

极客时间《Go 语言从入门到实践》学习笔记 11,题图来自网络

38 | 反射编程


其实之前对于 C# 和 Java 中的反射都有些概念模糊,看代码能看到,但是在项目中主动使用的很少。


反射最大的用途可能就是通过字符串或者以字符的形式来调用类型中的某一个方法,或者通过传入变量或者方法的名字访问某一个成员。


其实在 JavaScript 或者 Ruby 中也用到了反射,只是有时候用了而不自知。


对于留言中的问题,为什么 MethodByName 之前的 ValueOf 传递的参数是指针,而 FieldByName 之前 ValueOf 传递的是实例,我也不太明白,抄一段官方文档:


func (v Value) FieldByName(name string) Value
复制代码


FieldByName returns the struct field with the given name. It returns the zero Value if no field was found. It panics if v's Kind is not struct.


func (v Value) MethodByName(name string) Value
复制代码


MethodByName returns a function value corresponding to the method of v with the given name. The arguments to a Call on the returned function should not include a receiver; the returned function will always use v as the receiver. It returns the zero Value if no method was found.

39 | 万能程序


与配置有关的程序,很多都可以使用反射来写,其他语言或者框架也确实是这么做的。


在性能要求比较高的时候,要注意反射的性能。


反射代码的可读性也比较差,代码的 debug 难度也会增加。


抄一段课程中的代码


func fillBySettings(st interface{}, settings map[string]interface{}) error  {    // func(v value) Elem() Value    // Elem returns the value that the interface v contains or that the pointer    // It panics if v's kind is not Interface or Ptr    // It returns the zero Value if v is nil    // 因为要改变 st 的值,所以必须是一个指针,也必须是一个结构    // Elem() 获取指针指向的    if reflect.TypeOf(st).Kind() != reflect.Ptr {      if reflect.TypeOf(st).Elem().Kind() != reflect.Struct {            return errors.New("the first param should be a pointer to the struct type")  }    }}
复制代码


看了一下留言里面 @Geek_338030 和老师关于 FieldByName 的讨论,不明觉厉,先留个印象,以后看到相关代码再回来。

40 | 不安全编程


Go 语言不支持强制类型转换,那么一旦使用了不安全指针 unsafe.Pointer 指针,是可以把它“强制”转换成任意类型指针的。


unsafe 的使用场景主要是和外部的 c 程序的库


另外老师在留言回复里面解答了上一课的遗留问题,方法是定义在结构指针上的,所以要在指针对象上调用 MethodByName。另外,如果在指针值上调用 fieldByName,会产生一个 Panic。


我在测试的输出结果里面也看到了相同的值,代码和老师课程上的一致,暂时只能按照 @森美 同学的盲猜来解释。


代码和老师的 gitee 上的一致,部分输出如下: https://gitee.com/geektime-geekbang/go_learning/blob/master/code/ch39/unsafe_programming/unsafe_test.go 上的

发布于: 2021 年 04 月 24 日阅读数: 15
用户头像

escray

关注

Let's Go 2017.11.19 加入

Let's Go,用 100 天的时间从入门到入职

评论

发布
暂无评论
Golang 反射