Go Reflect Advanced Practices

Source: Internet
Author: User
  1. https://golang.org/pkg/reflect/The most important official documents, it is recommended to rough time to see this article first.
  2. Go's reflect is still relatively simple, can quickly get started.
  3. Https://github.com/golang/go/blob/master/src/reflect/type.go Https://github.com/golang/go/blob/master/src/reflect/value.go
    There are hundreds of panic in the source code, a variety of checks do a very comprehensive, have the idea of daring to try, as long as can run up, general problems.
  4. The actual use can not consider the impact of the use of reflect on performance, first realize the function, and then use benchmark test to optimize

When should I use reflect?

    1. 为了降低多写代码造成的bug率,做更好的规约和抽象。
    2. 为了灵活、好用、方便,做动态解析、调用和处理。
    3. 为了代码好看、易读、提高开发效率,补足与动态语言之间的一些差别

Remember! Reflect is not used to achieve your artifice! Use reflect to be enough!

Reflect Core

TypeOf (i interface{}) Type

Focus on this return value, it is an interface, the main implementation of it is struct rtype , this is also the core of the go type System, and Runtime/type.go struct _type consistent, here is not in-depth expansion, and then back again.

Type type interface {//Variable memory aligned, return rtype.align align () int//struct field for memory alignment, return rtype.fieldalign Fieldali GN () int//According to the incoming I, the method instance is returned, representing the type of the method of means (int) methods//Returns the method instance according to the name, this more commonly used Methodbyname (String) (method, BOOL)//return type the number of methods that can be exported in a method set Nummethod () int//return only type name, without package name name () string//Return import path, ie Pkgpath () string//returns rtype.size that is the type size, in bytes size () uintptr//return type name, which is actually Pkgpath () + name () string () string/ /return Rtype.kind, describe an underlying type kind () kind//check that the current type has no implementation interface U Implements (u type) bool//Check whether the current type can be assigned to interface U Assigna  Bleto (U type) bool//Check whether the current type can be converted to interface U type Convertibleto (u type) bool//Check whether the current type can do a comparison operation, in fact, is to see the type of the underlying there is no binding typealg Equal method. Stop! Don't search for typealg, or you'll get stuck in it!    Read the article first. Comparable () bool//return type bit size, but not all types can adjust this method, can not be adjusted panic Bits () int//Return channel type direction, if not channel, will panic C Handir () Chandir//Returns the last parameter of the function type is not a variable number, "..." In this case, again, if it is not a function type, it will panic isvariadic () bool    Returns the type of the contained element, only the Array, Chan, Map, PTR, Slice These can be adjusted, other types will panic, this is not nonsense?    Other types also do not contain element one said. Elem () type//returns the first field of the struct type, not the struct will panic,i out of bounds also panic field (i int) Structfield//As above, but nested calls, such as [1, 2] that is, returns the 2nd field of the 1th struct of the current struct, applies to the struct itself nested type Fieldbyindex (index []int) Structfield//By name to find the struct field, section Two return values OK indicates that there is no Fieldbyname (name string) (Structfield, BOOL)////The struct field is found by function name, because there may be a type func in the struct fieldby Namefunc (Match func (string) bool) (Structfield, BOOL)//Return function type of parameter I, not Func will panic in (i int) type//return  The type of the map key, not the map will panic key () type//returns the length of the array, not the array will panic Len () int//Returns the number of struct fields, not the struct     Will panic Numfield () int//Returns the number of arguments to the function, not Func will panic numin () int//return function return value number, not Func will panic numout () int Returns the type of the return value of function I, not the Func panic out (i int) type}

ValueOf (i interface{}) Value

Let's take a look at the definition, that's all.

type Value struct {    // 反射出来此值的类型,rtype 是啥往上看,但可别弄错了,这 typ 是未导出的,从外部调不到 Type 接口的方法    typ *rtype    // 数据形式的指针值    ptr unsafe.Pointer    // 保存元数据    flag}

The method of Value is too many, refer to the official document at the beginning, I choose a few points below to say, like len,cap this simple does not introduce:

// 前提 v 是一个 func,然后调用 v,并传入 in 参数,第一个参数是 in[0],第二个是 in[1],以此类推func (v Value) Call(in []Value) []Value// 返回 v 的接口值或者指针func (v Value) Elem() Value// 前提 v 是一个 struct,返回第 i 个字段,这个主要用于遍历func (v Value) Field(i int) Value// 前提 v 是一个 struct,根据字段名直接定位返回func (v Value) FieldByName(name string) Value// 前提 v 是 Array, Slice, String 之一,返回第 i 个元素,主要也是用于遍历,注意不能越界func (v Value) Index(i int) Value// 判断 v 是不是 nil,只有 chan, func, interface, map, pointer, slice 可以用,其他类型会 panicfunc (v Value) IsNil() bool// 判断 v 是否合法,如果返回 false,那么除了 String() 以外的其他方法调用都会 panic,事前检查是必要的func (v Value) IsValid() bool// 前提 v 是个 map,返回对应 valuefunc (v Value) MapIndex(key Value)// 前提 v 是个 map,返回所有 key 组成的一个 slicefunc (v Value) MapKeys() []Value// 前提 v 是个 struct,返回字段个数func (v Value) NumField() int// 赋值func (v Value) Set(x Value)// 类型func (v Value) Type() Type

Reflect scene Practice

Dynamic Call function (no parameter)

type T struct {}func main() {    name := "Do"    t := &T{}    reflect.ValueOf(t).MethodByName(name).Call(nil)}func (t *T) Do() {    fmt.Println("hello")}

Dynamic call function (with parameters)

type T struct{}func main() {    name := "Do"    t := &T{}    a := reflect.ValueOf(1111)    b := reflect.ValueOf("world")    in := []reflect.Value{a, b}    reflect.ValueOf(t).MethodByName(name).Call(in)}func (t *T) Do(a int, b string) {    fmt.Println("hello" + b, a)}

Handling errors in the return value

The return value is also the value type and, for errors, can be converted to interface after the assertion

type T struct{}func main() {    name := "Do"    t := &T{}    ret := reflect.ValueOf(t).MethodByName(name).Call(nil)    fmt.Printf("strValue: %[1]v\nerrValue: %[2]v\nstrType: %[1]T\nerrType: %[2]T", ret[0], ret[1].Interface().(error))}func (t *T) Do() (string, error) {    return "hello", errors.New("new error")}

struct Tag parsing

type T struct {    A int    `json:"aaa" test:"testaaa"`    B string `json:"bbb" test:"testbbb"`}func main() {    t := T{        A: 123,        B: "hello",    }    tt := reflect.TypeOf(t)    for i := 0; i < tt.NumField(); i++ {        field := tt.Field(i)        if json, ok := field.Tag.Lookup("json"); ok {            fmt.Println(json)        }        test := field.Tag.Get("test")        fmt.Println(test)    }}

Type conversions and Assignments

type T struct {    A int    `newT:"AA"`    B string `newT:"BB"`}type newT struct {    AA int    BB string}func main() {    t := T{        A: 123,        B: "hello",    }    tt := reflect.TypeOf(t)    tv := reflect.ValueOf(t)    newT := &newT{}    newTValue := reflect.ValueOf(newT)    for i := 0; i < tt.NumField(); i++ {        field := tt.Field(i)        newTTag := field.Tag.Get("newT")        tValue := tv.Field(i)        newTValue.Elem().FieldByName(newTTag).Set(tValue)    }    fmt.Println(newT)}

Processing different branches through kind ()

func main() {    a := 1    t := reflect.TypeOf(a)    switch t.Kind() {    case reflect.Int:        fmt.Println("int")    case reflect.String:        fmt.Println("string")    }}

Determine if an instance implements an interface

type IT interface {    test1()}type T struct {    A string}func (t *T) test1() {}func main() {    t := &T{}    ITF := reflect.TypeOf((*IT)(nil)).Elem()    tv := reflect.TypeOf(t)    fmt.Println(tv.Implements(ITF))}

Not to be continued

...

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.