go 反射规则
来源:互联网 发布:ps2000钢结构设计软件 编辑:程序博客网 时间:2024/06/05 04:49
反射规则
在计算机科学领域,反射是指一类应用,它们能够自描述和自控制。也就是说,这类应用通过采用某种机制来实现对自己行为的描述(self-representation)和监测(examination),并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义。
每个语言的反射模型都不同(同时许多语言根本不支持反射)。
Go语言实现了反射,所谓反射就是动态运行时的状态。
我们用到的包是reflect。
从接口值到反射对象的反射
反射仅是一种用来检测存储在接口变量内部(值value,实例类型concret type)pair对的一种机制。
在reflect反射包中有两种类型让我们可以访问接口变量内容
- reflect.ValueOf()
// ValueOf returns a new Value initialized to the concrete value// stored in the interface i. ValueOf(nil) returns the zero Value.func ValueOf(i interface{}) Value {...}
- reflect.TypeOf()
// TypeOf returns the reflection Type that represents the dynamic type of i.// If i is a nil interface value, TypeOf returns nil.func TypeOf(i interface{}) Type {...}
一个简单的案例:
package mainimport ( "reflect" "fmt")type ControllerInterface interface { Init(action string, method string)}type Controller struct { Action string Method string Tag string `json:"tag"`}func (c *Controller) Init(action string, method string){ c.Action = action c.Method = method}func main(){ //初始化 runController := &Controller{ Action:"Run1", Method:"GET", } //Controller实现了ControllerInterface方法,因此它就实现了ControllerInterface接口 var i ControllerInterface i = runController // 得到实际的值,通过v我们获取存储在里面的值,还可以去改变值 v := reflect.ValueOf(i) fmt.Println("value:",v) // 得到类型的元数据,通过t我们能获取类型定义里面的所有元素 t := reflect.TypeOf(i) fmt.Println("type:",t) // 转化为reflect对象之后我们就可以进行一些操作了,也就是将reflect对象转化成相应的值 ......}
打印结果:
value: &{Run1 GET}
type: *main.Controller
- v 是i接口为指向main包下struct Controller的指针(runController)目前的所存储值
- t 是i接口为指向main包下struct Controller的指针类型。
转换reflect对象之后操作
接口i所指向的对象的值操作
// Elem返回值v包含的接口controllerValue := v.Elem() fmt.Println("controllerType(reflect.Value):",controllerType)//获取存储在第一个字段里面的值fmt.Println("Action:", controllerValue.Field(0).String())
controllerType(reflect.Value): {Run1 GET }
Action: Run1
接口i所指向的对象的类型操作
获取定义在struct里面的标签
// Elem返回类型的元素类型。controllerType := t.Elem() tag := controllerType.Field(2).Tag //Field(第几个字段,index从0开始)fmt.Println("Tag:", tag)
Tag: json:”tag”
通过reflect.TypeOf(i)获取对象方法的信息
method, _ := t.MethodByName("Init")fmt.Println(method)
打印结果:{Init func(*main.Controller, string, string) <func(*main.Controller, string, string) Value> 0}
它返回了一个对象方法的信息集合即Method,关于Method结构定义在reflect/type.go下具体为:
// Method represents a single method.type Method struct { // Name is the method name. // PkgPath is the package path that qualifies a lower case (unexported) // method name. It is empty for upper case (exported) method names. // The combination of PkgPath and Name uniquely identifies a method // in a method set. // See http://golang.org/ref/spec#Uniqueness_of_identifiers Name string PkgPath string Type Type // method type Func Value // func with receiver as first argument Index int // index for Type.Method}
通过reflect.ValueOf(i)获取对象方法的信息
vMethod := v.MethodByName("Init")fmt.Println(vMethod)
通过reflect.ValueOf(i)调用方法
package mainimport ( "reflect" "fmt")type ControllerInterface interface { Init(action string, method string)}type Controller struct { Action string Method string Tag string `json:"tag"`}func (c *Controller) Init(action string, method string){ c.Action = action c.Method = method //增加fmt打印,便于看是否调用 fmt.Println("Init() is run.") fmt.Println("c:",c)}//增加一个无参数的Funcfunc (c *Controller) Test(){ fmt.Println("Test() is run.")}func main(){ //初始化 runController := &Controller{ Action:"Run1", Method:"GET", } //Controller实现了ControllerInterface方法,因此它就实现了ControllerInterface接口 var i ControllerInterface i = runController // 得到实际的值,通过v我们获取存储在里面的值,还可以去改变值 v := reflect.ValueOf(i) fmt.Println("value:",v) // 有输入参数的方法调用 // 构造输入参数 args1 := []reflect.Value{reflect.ValueOf("Run2"),reflect.ValueOf("POST")} // 通过v进行调用 v.MethodByName("Init").Call(args1) // 无输入参数的方法调用 // 构造zero value args2 := make([]reflect.Value, 0) // 通过v进行调用 v.MethodByName("Test").Call(args2)}
打印结果:value: &{Run1 GET }//有参数的FuncInit() is run.c: &{Run2 POST }//无参数的FuncTest() is run.
从反射对象到接口值的反射
修改反射对象
最近在写ATC框架,路由第一版构思中用到了反射就整理了下,不过经过几个莫名夜晚纠结,最终第二版构思实践中又把所有反射干掉了(泪…, 讨论群中一致认为反射对性能影响较大,能避免则避免,不能避免就少用。),目前思路和框架已定型,一个轻量级简单的RESTful go 框架 即将发布…
不早了,先到这里吧,米西米西了。空了在补充,还有很多反射内容待进一步完善……
有空的话就把beego框架中用到的反射知识整理分享下,利己利人。
- go 反射规则
- Go语言反射规则 - The Laws of Reflection
- Go语言反射规则 - The Laws of Reflection
- Go-反射
- Go 反射
- GO语言反射机制
- go-反射机制
- go语言反射reflect
- Go 反射 学习笔记
- Go 的反射
- Go反射reflection
- Go反射调用方法
- GoLang反射的规则
- [翻译]反射的规则
- GoLang反射的规则
- [翻译]反射的规则
- Go小计 - 可见性规则
- Go语言反射的使用
- 《Java编程技巧1001条》356条:建立随机浮点数
- Assertion failure in -[AFHTTPRequestSerializer requestWithMethod:URLString:parameters:error:]
- Java WebService
- html+css视频 89-91
- 前端 | 1
- go 反射规则
- 码云团队协作开发
- 关于数据库建模,概念模型、逻辑模型、物理模型的区别和转化
- Spring3与java8Failed to read candidate component class错误
- SMOTE实例代码
- 手机号输入实时验证
- 输入流简单汇总和用例结束的解决方式
- PowerDesigner V16.5 安装文件 及 破解文件
- IC验证简单介绍