Go 中的反射要点

bnbqian · · 3663 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

简介

反射是元数据编程的一种形式,指的是程序获得本身结构的一种能力。不同语言的反射模型实现不一样,本文中的反射,仅仅指的是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 < s.NumField(); i++ {
f := s.Field(i)
fmt.Printf("%d: %s %s = %v\n", i,
typeOfT.Field(i).Name, f.Type(), f.Interface())
}

参考

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

有疑问加站长微信联系(非本文作者)

本文来自:博客园

感谢作者:bnbqian

查看原文:Go 中的反射要点

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

3663 次点击  
加入收藏 微博
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传