Proper use of reflection in the Go language

  • 2020-06-01 10:03:01
  • OfStack

introduce

Reflection is a form of metadata programming that refers to the ability of a program to acquire its own structure. Different languages implement different reflection models. In this article, we only refer to the reflection model in Go language.

There are two problems with reflection that require three thoughts before use:

Heavy use of reflection results in a loss of 1 qualitative energy Clear is better than clever. Reflection is never clear.

There are some basic principles for the type design of Go, and understanding them will help you understand the nature of reflection:

Variables including < type, value > Two parts. Understand this point and you know why nil != nil .
type including static type and concrete type .simply put static type It's the type that you see when you're coding, concrete type Is the type seen by the runtime system.
The success of a type assertion depends on the value of the variable concrete type Rather than static type Therefore, an reader variable can also be type asserted as writer if its concrete type also implements the write method.
Reflection dependency in Go interface{} As a bridge, so follow principle 3. For example, the reflection package. The Kind method returns concrete type Rather than static type .

Needless to say, let's look at the sample code


package main
 
import (
    "fmt"
    "reflect"
)
 
type T struct {
    A int
    B string
}
 
func main() {
    t := T{23, "skidoo"}
    tt := reflect.TypeOf(t)
    fmt.Printf("t type:%v\n", tt)
    ttp := reflect.TypeOf(&t)
    fmt.Printf("t type:%v\n", ttp)
    // To set up the t , which needs to be passed in t Address instead of t A copy of the.
    // reflect.ValueOf(&t) just 1 The value of address, no settable, through .Elem() Dereferencing fetch t In and of itself reflect.Value
    s := reflect.ValueOf(&t).Elem()
    typeOfT := s.Type()
    for i := 0; i < s.NumField(); i++ {
        f := s.Field(i)
        fmt.Printf("%d: %s %s = %v\n", i,
            typeOfT.Field(i).Name, f.Type(), f.Interface())
    }
}
 
// The output
// t type:main.T
// t type:*main.T
// 0: A int = 23
// 1: B string = skidoo

conclusion

The above is the whole content of this article, I hope the content of this article to your study or work can bring 1 definite help, if you have questions you can leave a message to communicate.


Related articles: