内容简介:参考文章:
参考文章:
Go语言实战笔记(二十四)| Go 反射 (推荐去看)
Go语言实战笔记(二十五)| Go Struct Tag (推荐去看)
Go语言中反射包的实现原理(The Laws of Reflection)
和 Java 语言一样,Go也实现运行时反射,这为我们提供一种可以在运行时操作任意类型对象的能力。Go是静态类型化的。每个变量都有一个静态类型,也就是说,在编译的时候变量的类型就被很精确地确定下来了,比如要么是int,或者是float32,或者是MyType类型,或者是[]byte等等。
1、第一反射定律(接口值到反射对象的反射)TypeOf和ValueOf
在 Go 的反射定义中,任何接口都会由两部分组成的,一个是接口的具体类型,一个是具体类型对应的值。比如 var i int = 3 ,因为 interface{} 可以表示任何类型,所以变量 i 可以转为 interface{} ,所以可以把变量 i 当成一个接口,那么这个变量在Go反射中的表示就是 <Value,Type> ,其中Value为变量的值 3 ,Type变量的为类型 int 。
reflect.Typeof获取具体的类型;reflect.Valueof获取接口的value。
type Myint int
type User struct {
name string
age int
}
func main() {
u := User{name:"lyd",age:24}
var num Myint = 18
t := reflect.TypeOf(u) //main.User
v := reflect.ValueOf(u) //{lyd 24}
t_num := reflect.TypeOf(num) //main.Myint
v_num := reflect.ValueOf(num) //18
}
//还可以这样打印
fmt.Printf("%T\n",u)
fmt.Printf("%v\n",u)
v.Type() //main.User复制代码
2、将reflect.Value转原始类型(第二反射定律)
上面的例子我们可以通过 reflect.ValueOf 函数把任意类型的对象转为一个 reflect.Value ,给定一个reflect.Value,我们能用Interface方法把它恢复成一个接口值;
type Myint int
type User struct {
name string
age int
}
func main() {
u := User{name:"lyd",age:24}
var num Myint = 18
v := reflect.ValueOf(u)
v_num := reflect.ValueOf(num)
y := v.Interface().(User)
//fmt.Println可以处理interface{}, 所以可以直接
y_num := v_num.Interface()
fmt.Println(y,y_num) //{lyd 24} 18
}
复制代码
3、修改反射对象的值(第三反射定律)
reflect.ValueOf 函数返回的是一份值的拷贝,所以前提是我们是传入要修改变量的地址。 其次需要我们调用 Elem 方法找到这个指针指向的值。
Value 为我们提供了 CanSet 方法可以帮助我们判断Value的settablity
一:反射对象不是settable的
func main() {
var x float64 = 3.4
v := reflect.ValueOf(x)
v.SetFloat(7.1) // Error: will panic.
}
复制代码
func main() {
var x float64 = 3.4
v := reflect.ValueOf(x)
fmt.Println("settability of v:", v.CanSet()) //settability of v: false
}
复制代码
var x float64 = 3.4
p := reflect.ValueOf(&x) // Note: take the address of x.注意这里哦!我们把x地址传进去了!
fmt.Println("type of p:", p.Type()) // type of p: *float64
fmt.Println("settability of p:", p.CanSet()) //settability of p: false
复制代码
反射对象p不是settable的,但是我们想要设置的不是p,而是(效果上来说)*p。为了得到p指向的东西,我们调用Value的Elem方法
二:总之,下面这样才是可以改变值的
func main() {
x:=2
v:=reflect.ValueOf(&x)
v.Elem().SetInt(100)
fmt.Println(x)
}复制代码
4、获取底层类型
type User struct {
name string
age int
}
func main() {
u := User{name:"lyd",age:24}
t := reflect.TypeOf(u)
v := reflect.ValueOf(u)
fmt.Println(t.Kind(),v.Kind()) //struct struct
}
复制代码
5、遍历字段和方法
通过反射,我们可以获取一个结构体类型的字段,也可以获取一个类型的导出方法
type User struct {
name string
age int
}
func main() {
u := User{name:"lyd",age:24}
t := reflect.TypeOf(u)
for i:=0;i<t.NumField();i++ {
fmt.Println(t.Field(i).Name)
}
}
//name
//age复制代码
//方法
for i:=0;i<t.NumMethod() ;i++ {
fmt.Println(t.Method(i).Name)
}复制代码
6、动态调用方法
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
An Introduction to Genetic Algorithms
Melanie Mitchell / MIT Press / 1998-2-6 / USD 45.00
Genetic algorithms have been used in science and engineering as adaptive algorithms for solving practical problems and as computational models of natural evolutionary systems. This brief, accessible i......一起来看看 《An Introduction to Genetic Algorithms》 这本书的介绍吧!