Go 中的反射要点

时间:2021-09-05 15:15:01

简介

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

类型以及接口

这个基本概念需要清晰,这里不详细展开。

基本类型就是一个值,接口类型是(值,类型)对。

看下面两个图:

Go 中的反射要点

Go 中的反射要点

当然还有一些内存优化的东西,这里也不展开。

接口对象到反射对象

反射只是从接口变量里面读取类型和值对。类型和值就是我们要的反射对象。

package main

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

类型

// TypeOf returns the reflection Type of the value in the interface{}.
func TypeOf(i interface{}) Type

var x float64 = 3.4
fmt.Println("value:", reflect.ValueOf(x))

反射对象到接口对象

y := v.Interface().(float64) // y will have type float64.
fmt.Println(y)

这里可以把Interface()看作ValueOf()的逆操作,只不过返回值类型永远是静态的interface{}。

要修改反射对象,值必须是settable

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

我们可以把指针传进去,然后就可以干了。

var x float64 = 3.4
p := reflect.ValueOf(&x) // Note: take the address of x.
fmt.Println("type of p:", p.Type())
fmt.Println("settability of p:", p.CanSet())
v := p.Elem()
fmt.Println("settability of v:", v.CanSet())

下面是一个比较完整的反射修改的例子:

type T struct {
A int
B string
}
t := T{23, "skidoo"}
s := reflect.ValueOf(&t).Elem()
typeOfT := s.Type()
for i := 0; i

参考

http://blog.golang.org/laws-of-reflection