GOLANG 反射法则

译自[blog.golang.org/laws-of-reflection]

在计算机中, 反射是程序通过类型,检测到它自己的结构能力;是一种元编程程;也是一个具大的混淆点

在本文中,我们将通过解释反射是如何在GO中工作的来澄清它。每个语言的反射模式是不同的。本文着重于GO,
所以后文中的反射都是指GO中的反射

1.类型和接口
因为反射是修建于类型系统之上, 所以让我们从GO的类型开始讲吧。
GO是静态类型语言。 每个变量都有一个静态类型。 也就是说, 每一个已经类型在编译时已经固定了其类型:int, float32...等
假如我们声明如下:
type MyInt int
var i int
var j MyInt
则i的类型为int; j的类型为MyInt;变量i和j有明显不同的静态类型, 而潜在下层类型, 他们可以彼此赋值不须要转换。
还有一种重要类型是接口类型,它代表了一组固定的方法集。一个接口变量能存储任一实体值,只要它实现了接口方法集。以大家所
熟知的接口为例, io.Reader和io.Writer, 它们的类型摘自io 包。

// Reader 就是一个包含了基本读方法的接口
type Reader interface {
    Read(p []byte[(n int, err error)
}
// Writher就是一个包含了基本写方法的接口
type Writer interface{
    Write(p []byte)(n int, err error);
}

任何实现了上述读(写)方法签名的类型就说它实现了io.Reader(或者io.Writer).讨论这个的目标是, 就是指一个io.Reader类型的变量
可以带有任何值,只要它的类型中有一个Read方法
var r io.Reader
r = os.Stdin
r = bufio.NewReader(r)
r = new (bytes.Buffer)
// 等等 ....都可以的...

无论r带有什么实例值,r的类型总是io.Reader,明白这点是非常重要的;GO是静态类型,r的静态类型就是io.Reader。
另一个极其重要的接口例子就是空接口
interface{}
它代表一个空方法集。它可以被任何值满足。因为任何值都有0到多个方法
有些朋友说,GO的接口是动态类型的, 这就是错误引导。 他们是确实静态类型:一个接口类型的变量总是有一个相同的静态类型,
虽然,在运行时,一个存储在一个接口变量上的值可能会改变类型,但值总是满足接口。
我们需要准确的了解这些,因为反射和接口太相似了。

2. 接口的表达
Russ Cox写了一篇博客关于GO语言接口值的表达【research.swtch.com/interface】, 我就没有必须重复这个故事了。简单总结如下
接口类型的变量存成一个pair(对):值赋给变量和它的描述符descriptor;更准确的说,就是潜在下层的实例值实现了接口,它的类型
描述了下层实例值的完整类型。例如:
var r io.Reader
tty , err := os.OpenFile("/dev/tty",os.O_RDWR, 0)
if er != nil{
    return nil, err
}
r = tty

r包含了(值value,类型type)pair对,(tty,*os.File). 注意,*os.File类型实现了远不只Read方法;虽然接口值提供只有Read方法。
内部值包含所有关于值的类型信息,这就是为什么我们可以如下处理
var w io.Writer
w = r.(io.Writer) // 类型断言转换
这在个赋值表达式中是一个类型断言;它判言的是r里面的东西也实现了io.writer.并且我们能赋值给w, 赋值后,w包含(tty,*os.File)对。
和之前r所包含的对是一样的的。接口的静态类型确定了通过接口变量那些方法可以被调用。虽然内部实例值可能有一个更大的方法集。
接着,我们也可以
var empty interface{}
empty = w
我们的空接口值empty,再一次包含了一样的(tty,*os.File)对。这是很方便的, 空接口可以含有什么信息
一个重要的细节就是, 内部pair对总是有一个(值value,实类型concrete type)并且没有(value, 接口类型interface type)

现在我们可以谈反射了
。。。。。。。待续

时间: 2024-07-31 13:18:47

GOLANG 反射法则的相关文章

golang反射初试

golang反射来自Go AST(Abstract Syntax Tree). reflect操作更多像traverse AST. t := reflect.TypeOf(obj) 使用TypeOf()获取类型信息. v := reflect.ValueOf(obj) 使用ValueOf获取值信息 如果t是Array, Slice, Map, Chan或Pointer,可以继续继续使用Elem()方法获取其元素的更多信息. Elem(): 必须是Array, Slice, Map, Chan或

golang 反射应用(二)

golang反射应用(二) package test import ( "reflect" "testing" ) //定义适配器 func TestReflect(t *testing.T){ //声明回调函数 call1 := func(v1,v2 int){ t.Log(v1,v2) //1 2 } call2 := func(v1,v2 int,s string){ t.Log(v1,v2,s) //1 2 test2 } //定义全局变量 var ( fu

[golang]反射的用处--代码自动生成

背景: go语言处理db.json的时候,具体代码的变量定义和db字段.json输出的时候可能不一样. 这个时候,我们需要用tag的方式来进行定义. 例如: type MyStruct struct { Name string `json:"name"` MaxHeight int `json:"max_height"` } 如果字段或结构体非常多的话,有十几二十几个,就非常的麻烦. 因此,就利用golang的反射,做了一个小工具来自动生成,具体使用如下: //你的

golang 反射

转自:http://golanghome.com/post/546 自己在用Go写Web框架时,遇到要从接口中返回对象信息的技术问题.网上关于Go中接口反射的资料较少,所以自己学习了一段时间,特将结果与大家分享. 代码约定 import ( "fmt" "reflect" ) type boy struct { Name string age int } type human interface { SayName() SayAge() } func (this *

golang 反射解惑

Type和Kind的区别 直接看例子: type Myint int type Person struct { } func main() { var myint Myint= 1 var person Person= Person{} s := 1 var intPtr =&s mySlice := []string{} myMap := map[string]int{} myintType := reflect.TypeOf(myint) personType := reflect.Type

GO开发[六]:golang反射(reflect)

反射 反射:可以在运行时动态获取变量的相关信息 ? Import ("reflect") reflect.TypeOf,获取变量的类型,返回reflect.Type类型 reflect.ValueOf,获取变量的值,返回reflect.Value类型 reflect.Value.Kind,获取变量的类别,返回一个常量 reflect.Value.Interface(),转换成interface{}类型 获取变量的值: reflect.ValueOf(x).Float() reflect

golang反射

反射reflection 反射可大大提高程序的灵活性,使得interface{}有更大的发挥余地 反射使用TypeOf和ValueOf函数从接口中获取目标对象信息 反射会将匿名字段作为独立字段(匿名字段本质) 想要利用反射修改对象状态,前提是interface.data是settable,即pointer-interface 通过反射可以"动态"调用方法 对某一个struct进行反射的基本操作 package main import ( "fmt" "re

局部光照模型

提要 常见的光照模型一般包括四个部分ambient, diffuse, specular, 和emitted light. 即: vertex color = ambient + diffuse + specular + emitted light 当有多个光源的时候,最后的颜色就是多个结果的叠加. Ambient light:环境光,通常定义在光源的中,注意每个光源的衰减量. Diffuse:漫反射部分,光照找到物体的表面,由于物体的表面凹凸不平而反射到各个方向的光. Specular :相比

Golang-interface(四 反射)

github:https://github.com/ZhangzheBJUT/blog/blob/master/reflect.md 一 反射的规则 反射是程序运行时检查其所拥有的结构,尤其是类型的一种能力:这是元编程的一种形式.它同时也是造成混淆的重要来源. 每个语言的反射模型都不同(同时许多语言根本不支持反射).本节将试图明确解释在 Go 中的反射是如何工作的. 1. 从接口值到反射对象的反射 在基本的层面上,反射只是一个检查存储在接口变量中的类型和值的算法.在 reflect 包中有两个类