欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Go语言中反射的正确使用

程序员文章站 2022-04-10 12:17:23
介绍 反射是元数据编程的一种形式,指的是程序获得本身结构的一种能力。不同语言的反射模型实现不一样,本文中的反射,仅仅指的是go语言中的反射模型。 反射有两个问题,在使用...

介绍

反射是元数据编程的一种形式,指的是程序获得本身结构的一种能力。不同语言的反射模型实现不一样,本文中的反射,仅仅指的是go语言中的反射模型。

反射有两个问题,在使用前需要三思:

  1. 大量的使用反射会损失一定性能
  2. clear is better than clever. reflection is never clear.

go的类型设计上有一些基本原则,理解这些基本原则会有助于你理解反射的本质:

  1. 变量包括 <type, value> 两部分。理解这一点你就知道为什么nil != nil了。
  2. type包括 static typeconcrete type. 简单来说 static type是你在编码是看见的类型,concrete type是runtime系统看见的类型。
  3. 类型断言能否成功,取决于变量的concrete type,而不是static type. 因此,一个 reader变量如果它的concrete type也实现了write方法的话,它也可以被类型断言为writer.
  4. go中的反射依靠interface{}作为桥梁,因此遵循原则3. 例如,反射包.kind方法返回的是concrete type, 而不是static type.

多说无用,下面来看示例代码

复制代码 代码如下:

package main
 
import (
    "fmt"
    "reflect"
)
 
type t struct {
    a int
    b string
}
 
func main() {
    t := t{23, "skidoo"}
    tt := reflect.typeof(t)
    fmt.printf("t type:%v\n", tt)
    ttp := reflect.typeof(&t)
    fmt.printf("t type:%v\n", ttp)
    // 要设置t的值,需要传入t的地址,而不是t的拷贝。
    // reflect.valueof(&t)只是一个地址的值,不是settable, 通过.elem()解引用获取t本身的reflect.value
    s := reflect.valueof(&t).elem()
    typeoft := s.type()
    for i := 0; i < s.numfield(); i++ {
        f := s.field(i)
        fmt.printf("%d: %s %s = %v\n", i,
            typeoft.field(i).name, f.type(), f.interface())
    }
}
 
// 输出结果
// t type:main.t
// t type:*main.t
// 0: a int = 23
// 1: b string = skidoo

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。