Home  >  Article  >  Backend Development  >  An article teaches you the basics of reflection in Go language

An article teaches you the basics of reflection in Go language

Go语言进阶学习
Go语言进阶学习forward
2023-07-25 17:01:581163browse

What is reflection

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 avariable 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

An article teaches you the basics of reflection in Go language

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.


Reflection (reflect package)

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.

TypeOf

##TypeOf

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)
}

main

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)
}

执行结果

An article teaches you the basics of reflection in Go language

通过reflect.TypeOf方法,完美解决上述需求。

TypeOf 的Name和Kind

这个是啥意思呢??这个在结构体中比较好体现。

简答来说就是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
}
main
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)
}

执行结果

An article teaches you the basics of reflection in Go language

总结

经过对比,会发现几个特殊问题。

如果变量是指针类型Name为空,Kindptr

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.

ValueOf

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牛叉的是,它里面还包括了变量类型

注:ValueOfTypeOfKind属性返回内容是一摸一样的。

需求:定义一个函数,可以接收任意类型,通过反射得出变量类型和变量值。

函数

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下去
  }
}

main

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)
}

执行结果

An article teaches you the basics of reflection in Go language

通过反射设置值

反射还有一个用途,就是动态的修改变量值,可能你暂时体会不到,但是语法还是要学的。

通过反射设置值,需要用到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)
  }
}

main

func main() {
  var a int = 10
  fmt.Printf("a的值:%v\n", a)
  //反射修改值传入的必须是地址
  reflectSetValue(&a)
  fmt.Printf("a的值:%v\n", a)
}

执行结果

An article teaches you the basics of reflection in Go language

Summary

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 ValueOfUse 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!

Statement:
This article is reproduced at:Go语言进阶学习. If there is any infringement, please contact admin@php.cn delete