golang

golang 理解 reflect包 函数 ValueOf, Value.Set

亡梦爱人 提交于 2019-12-05 01:03:09
最近golang 项目需要一个通用函数,更新结构体中的数据。查看资料需要用到反射机制,之前对反射机制理解不深,费了些周折,终于有所理解,记录于此,供自己和大家参考。 理解interface{}变量 理解reflect 机制很重要一点,本人觉得关键需要理解把一个变量传给下面例子函数的interface{}参数后,interface{}获取了变量的哪些信息。 func reload(i interface{}) { } 通过reflect的 unpackEface 函数可以推测变量传给interface{}参数后,会把参数信息存储到emptyInterface结构体中 func unpackEface(i interface{}) Value { e := (*emptyInterface)(unsafe.Pointer(&i)) // NOTE: don't read e.word until we know whether it is really a pointer or not. t := e.typ if t == nil { return Value{} } f := flag(t.Kind()) if ifaceIndir(t) { f |= flagIndir } return Value{t, e.word, f} }

Golang之反射reflect包

…衆ロ難τιáo~ 提交于 2019-12-05 01:02:59
反射规则 在计算机科学领域,反射是指一类应用,它们能够自描述和自控制。也就是说,这类应用通过采用某种机制来实现对自己行为的描述(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

利用golang的反射包,实现根据函数名自动调用函数。

我怕爱的太早我们不能终老 提交于 2019-12-05 01:02:11
package main import "fmt" import "reflect" import "encoding/xml" type st struct{ } func (this *st)Echo(){ fmt.Println("echo()") } func (this *st)Echo2(){ fmt.Println("echo--------------------()") } var xmlstr string=`<root> <func>Echo</func> <func>Echo2</func> </root>` type st2 struct{ E []string `xml:"func"` } func main() { s2 := st2{} xml.Unmarshal([]byte(xmlstr), &s2) s := &st{} v := reflect.ValueOf(s) v.MethodByName(s2.E[1]).Call(nil) } 利用golang的反射包,实现根据函数名自动调用函数。 来源: CSDN 作者: rufidmx 链接: https://blog.csdn.net/rufidmx/article/details/18226649

golang中builtin包说明

一曲冷凌霜 提交于 2019-12-05 01:01:57
builtin包是go的预声明定义,包括go语言中常用的各种类型和方法声明,包括变量和常量两部分.其详细声明在builtin.go文件中,链接:http://golang.org/src/builtin/builtin.go 首先介绍一下golang中常量. 常量: const ( true = 0 == 0 // Untyped bool. false = 0 != 0 // Untyped bool. ) true和false是两个无类型的bool值 const iota = 0 // Untyped int.无类型int iota是预声明标示符,它只能用在常量声明中 ,并且其值从0开始,在const中每新增一行将使得iota计数一次,即iota自己增长1(从这点来看,iota可以看成const块中的行索引,记录行数),其值一直自增1直到遇到下一个const关键字,其值才被重新置为0. 1在常量声明中,如果一个常量没有赋值,则他就跟上一行的赋值相同,这个可以用在如果多个常量其值相同时,则只需给1个常量赋值,其他常量跟在他后面即可. package main import ( "fmt" ) const ( a = iota   //iota默认初始值为0 b = 100 c      //c默认跟上一个赋值相同 d = iota   //iota默认每行加1,故此时其值为3 )

Golang反射调用函数

十年热恋 提交于 2019-12-05 01:01:38
首先,来看看这段 PHP 代码: view source print ? 1 function foobar() { 2 echo "Hello Golang\n" ; 3 } 4 $funcs = array ( 5 "foobar" => "foobar" , 6 "hello" => "foobar" , 7 ); 8 $funcs [ "foobar" ](); 9 $funcs [ "hello" ](); 它会输出: view source print ? 1 mikespook@mikespook-laptop:~/Desktop$ phpfoobar.php 2 HelloGolang 3 HelloGolang 用这个方法调用匹配名字的函数,非常有效。 那么,在 Golang 中是否可能用函数的名字来调用某个函数呢? 作为一个静态、编译型语言,答案是否定的……又是肯定的! 在 Golang 中,你不能这样做: view source print ? 01 func foobar(){ 02 //bla...bla...bla... 03 } 04 funcname := "foobar" 05 funcname() 06 不过可以: 07 08 func foobar(){ 09 //bla...bla...bla... 10 } 11 funcs :=map

golang reflect 反射机制

ε祈祈猫儿з 提交于 2019-12-05 00:57:25
反射 The Laws of Reflection The Laws of Reflection Go Data Structures: Interfaces 介绍 在这篇文章中我们将讲解golang的reflect是如何工作的,每一门语言的反射模型都不同,并且语多语言也不支持 Types and interface 由于reflect是在类型(type)系统上建立的,所以我们先从类型开始复习. Go是一个静态语言,每一个变量都有一个静态类型, 如 int, float32, *MyType, []byte等,如果我们声名如下的代码 type MyInt int var i int var j MyInt 则i的类型为int, j的类型为MyInt. 虽然变量i和j的底层类型都是int, 但变量i和j的类型是有明显的区别的, 它们彼此不能直接进行赋值,必须通过转换. 非常重要的一个类型种类为interface类型,它表示固定的方法集。一个interface变量可以存放作何具体的值, 只要它实现了了interface包含的方法. 众所周知的一个例子是io package的 io.Reader和io.Writer // Reader is the interface that wraps the basic Read method. type Reader interface {

golang 反射(reflect)

感情迁移 提交于 2019-12-05 00:57:13
golang 反射(reflect) 反射是现代程序必备的元素,用于在 运行时 获取程序元素,如对象等的 元数据 ,实现动态识别类型及其结构,以及相关的语义信息。 反射在程序中应用非常多,例如: 动态生成数据:json 序列化/反序列化; orm 映射, proxy 透明代理对象 动态调用方法:plugin 实现 框架自动处理程序:annotation tag 注解标签 其他需要数据元数据的应用 在必要的场合,灵活应用反射,是中高级程序员能力的评价标准之一。灵活应用的根本是加深对 go 语言编译与实现的理解,并阅读典型应用案例。 滥用反射 ,也是低中级程序员最常见的问题,造成程序效率底下、不确定性错误增多。 一、Go 中的反射 go 是静态语言,表示内存中任何一个数据对象(data object)的值及其类型必须是编译期可确定的。因此,go 应用运行时不会像 java 等动态语言一样,在运行期维护所有对象的元数据,以支持多态等需要。也不像 c 语言,不提供任何元数据支持。 但注定 go 语言的反射是简单和有限的。 大神文章,必读!必读!必读!在短短的文章中,说明了 go 语言反射的要点! The Laws of Reflection 其中文翻译 “反射三法则[ https://blog.go-zh.org/laws-of-reflection] ” 请使用 $go tool

golang---利用反射机制对结构体进行循环赋值

江枫思渺然 提交于 2019-12-05 00:53:14
熟悉C语言的朋友都知道,C语言的指针操作某些方面是很方便的。 如假设你知道内存中有一个连续100个字节的区域,或者你有一个连续100个字节的字节数组,你需要用其对一个已经定义好的结构体进行赋值,在c语言你可以简单地将内存数据中的头地址,或者字节数组的头地址赋值给结构体指针就行。 但在go语言中该如何实现? 假设你有如下的golng结构体: 这个结构体的数据可以对应一个byte[100]字节组。 例如 DTemp_Des 字段的低位时b[1],高位是b[2] Temp_Des 的低位时b[3],高位b[4] 如此类推 但你对这个结构体赋值的时候你不能笨笨地一个个赋值,如果字段少还可以,字段多比如100个字段,那你会疯掉 笨的做法: nm:=&NM820_SysVal{} nm.DTemp_Des=uint16(b[1])+uint16(b[2]<<8) ........ 一个个赋值 详细代码如下 注意: 1.开头要引入reflect包 2.变量nm为结构体指针 3.数组b用于结构体赋值的字节数组 来源: CSDN 作者: 鱼鱼AA 链接: https://blog.csdn.net/qq317808023/article/details/50192897

Golang Reflect反射

∥☆過路亽.° 提交于 2019-12-05 00:50:25
Go是静态类型语言。每个变量都拥有一个静态类型,这意味着每个变量的类型在编译时都是确定的:int,float32, *AutoType, []byte, chan []int 诸如此类。 动静类型 编译时就知道变量类型的是静态类型;运行时才知道一个变量类型的叫做动态类型。 1. 静态类型 静态类型就是变量声明时的赋予的类型。比如: type MyInt int // int 就是静态类型 type A struct { Name string // string就是静态 } var i * int // *int就是静态类型 2. 动态类型 动态类型:运行时给这个变量复制时,这个值的类型(如果值为nil的时候没有动态类型)。一个变量的动态类型在运行时可能改变,这主要依赖于它的赋值(前提是这个变量时接口类型)。 var A interface { } // 静态类型interface{} A = 10 // 静态类型为interface{} 动态为int A = "String" // 静态类型为interface{} 动态为string var M * int A = M // 猜猜这个呢? 来看看这个例子: //定义一个接口 type Abc interface { String ( ) string } // 类型 type Efg struct { data string }

Golang反射机制的实现分析——reflect.Type类型名称

你离开我真会死。 提交于 2019-12-05 00:44:29
现在越来越多的java、php或者python程序员转向了Golang。其中一个比较重要的原因是,它和C/C++一样,可以编译成机器码运行,这保证了执行的效率。在上述解释型语言中,它们都支持了“反射”机制,让程序员可以很方便的构建一些动态逻辑。这是C/C++相对薄弱的环节,而Golang却有良好的支持。本系列,我们将通过反汇编Golang的编译结果,探究其反射实现的机制。 (转载请指明出于breaksoftware的csdn博客) 为了防止编译器做优化,例子中的源码都通过下面的指令编译 go build -gcflags "-N -l" [xxxxxx].go 类型名称 基本类型 package main import ( "fmt" "reflect" ) func main() { t := reflect.TypeOf(1) s := t.Name() fmt.Println(s) } 这段代码最终将打印出1的类型——int。 main函数的入口地址是main.main。我们使用gdb在这个位置下断点,然后反汇编。略去一部分函数准备工作,我们看到 0x0000000000487c6f <+31>: mov %rbp,0xa0(%rsp) 0x0000000000487c77 <+39>: lea 0xa0(%rsp),%rbp 0x0000000000487c7f <+47>