Reflection, um..., means reverse, that is, turning things over.
For example, a very simple code like this.
var a int = 3 fmt.Println(a)
Of course we know that the a
variable isint
type, but thinking about it the other way around, how does the program know that a
is What about the int
type? ? ?
At this time, you need to use reflection.
Sample code
v := reflect.TypeOf(a) fmt.Println(v)
The two codes are combined into one execution result
The second line of code successfully restored the variable a
to int
type.
What? ? ? What use are you to me? ? ? ,Um. . . To be honest, I don’t use it too much, but I have to know how to do it.
In Go, any variable , both have concrete types and concrete values , just like var a int = 3
, The specific type is int
, The specific value is 3
.
So, the specific type of the variable belongs to reflect.Type
, the specific value of the variable belongs to reflect.Value
.
And Go provides
##reflect.TypeOf Get the specific type.
##reflect.ValueOfGet the specific value.
method can get the # of the variable
##Specific type. There is a need to define a function that can receive any type of data and print the variable type through reflection.
func reflectType(x interface{}) { v := reflect.TypeOf(x) fmt.Printf("你传入的变量类型是:%v\n",v) }
func main() { var a int = 666 var b float64 = 3.14 var c string = "hello world" var d [3]int = [3]int{1,2,6} var e []int = []int{1,2,6,88} var f map[string]interface{} = map[string]interface{}{ "Name":"张三", "Age":18, } reflectType(a) reflectType(b) reflectType(c) reflectType(d) reflectType(e) reflectType(f) }
通过reflect.TypeOf
方法,完美解决上述需求。
这个是啥意思呢??这个在结构体中比较好体现。
简答来说就是TypeOf
返回的太笼统了,还有更加细化的类型,通过这俩属性获取。
func reflectType(x interface{}) { v := reflect.TypeOf(x) fmt.Printf("你传入的变量类型是:%v | Name:%v | Kind:%v\n", v, v.Name(), v.Kind()) }
type Student struct { Name string Age int }
func main() { var a int var b *int var c []int var d map[string]interface{} var e Student reflectType(a) reflectType(b) reflectType(c) reflectType(d) reflectType(e) }
经过对比,会发现几个特殊问题。
如果变量是指针类型,Name
为空,Kind
是ptr
。
If the variable is a reference type (slice and map) type, Name
is empty, only Kind
.
If the variable is a structure, Name
is the structure name, Kind
is struct
.
TypeOf
can only get the ## of the variable in reverse #Specific type, but you cannot get the specific value, which is a bit unkind.
所以ValueOf
就来解决这个问题了,但是ValueOf
牛叉的是,它里面还包括了变量类型。
注:ValueOf
和TypeOf
的Kind
属性返回内容是一摸一样的。
需求:定义一个函数,可以接收任意类型,通过反射得出变量类型和变量值。
func reflectType(x interface{}) { v := reflect.ValueOf(x) k := v.Kind() switch k { case reflect.Int: fmt.Printf("我是Int类型,我的值是%v\n",v.Int()) case reflect.Slice: fmt.Printf("我是切片类型,我的值是%v\n",v.Slice(1,2)) case reflect.Map: fmt.Printf("我是切片类型,我的值是%v\n",v.MapKeys()) //case :可以继续case下去 } }
func main() { var a int = 1 var c []int = []int{1, 5, 7, 19} var d map[string]interface{} = map[string]interface{}{ "Name": "你好", "Age": 18, } var e Student reflectType(a) reflectType(c) reflectType(d) reflectType(e) }
反射还有一个用途,就是动态的修改变量值,可能你暂时体会不到,但是语法还是要学的。
通过反射设置值,需要用到Elem
方法,并且传入的必须是指针。
示例代码
func reflectSetValue(x interface{}) { v := reflect.ValueOf(x) //kind也必须是Elem调用 var k = v.Elem().Kind() switch k { case reflect.Int: //反射修改必须通过Elem v.Elem().SetInt(200) } }
func main() { var a int = 10 fmt.Printf("a的值:%v\n", a) //反射修改值传入的必须是地址 reflectSetValue(&a) fmt.Printf("a的值:%v\n", a) }
We have learned the basic reflection of GoTypeOf
, Name and Kind of TypeOf
,ValueOf
, Set the value via reflection
.
whereKind
is in Type
# Both ## and ValueOf are available, usually TypeOf
and ValueOf
Use together for better results!
Reflection may not be easy to understand, so you must work harder! persist in! !
The above is the detailed content of An article teaches you the basics of reflection in Go language. For more information, please follow other related articles on the PHP Chinese website!