Golang reflect

·

2 min read

What Reflect can be used for.

Reflection can be used to examine type and value info at runtime.

How to get the actual type of an interface.

package main

import (
    "fmt"
    "reflect"
)

func typeOf(vals ...interface{}) {
    for _, v := range vals {
        fmt.Printf("val: %v, type: %v\n", v, reflect.TypeOf(v))
    }
}

type XS struct{}

func main() {
    var x bool = true
    fmt.Println("x type: ", reflect.TypeOf(x))

    typeOf(1, int64(100), int32(666), 1.1, "A", true, &XS{})
}
/*
x type:  bool
val: 1, type: int
val: 100, type: int64
val: 666, type: int32
val: 1.1, type: float64
val: A, type: string
val: true, type: bool
val: &{}, type: *main.XS
*/

reflect.TypeOf returns the Type of the interface variable.

Inspect struct.

package main

import (
    "fmt"
    "reflect"
)

type Programmer struct {
    Name     string
    Age      uint
    LangList []string
    Salary   float32
}

func main() {
    s := Programmer{
        Name:     "Bob",
        Age:      26,
        LangList: []string{"GO", "Java", "Python"},
        Salary:   1000000,
    }
    fmt.Printf("inspecting strcut: %+v\n", s)
    t := reflect.TypeOf(s)

    if t.Kind() != reflect.Struct {
        fmt.Println(s, " is not a struct")
        return
    }

    for i := 0; i < t.NumField(); i++ {
        f := t.Field(i)
        fmt.Printf("field: %s, type: %v\n", f.Name, f.Type.Kind())
    }
}
/*
inspecting strcut: {Name:Bob Age:26 LangList:[GO Java Python] Salary:1e+06}
field: Name, type: string
field: Age, type: uint
field: LangList, type: slice
field: Salary, type: float32
*/

Get Struct’s Field value

package main

import (
    "fmt"
    "reflect"
)

type Programmer struct {
    Name     string   `tag:"name"`
    Age      uint     `tag:"age"`
    LangList []string `tag:"lang_list"`
    Salary   float32  `tag:"salary"`
}

func GetStructTag(s interface{}) {
    structValue := reflect.ValueOf(s)
    structType := reflect.TypeOf(s)
    for i := 0; i < structValue.NumField(); i++ {
        f := structValue.Field(i)
        value := f.Interface()
        tp := structType.Field(i)
        fmt.Printf("fieldValue: %v, type: %v, tagName: %s\n", value, tp.Type.Kind(), tp.Tag.Get("tag"))
    }
}

func main() {
    GetStructTag(Programmer{
        Name:     "Bob",
        Age:      26,
        LangList: []string{"GO", "Java", "Python"},
        Salary:   1000000,
    })
}
/*
fieldValue: Bob, type: string, tagName: name
fieldValue: 26, type: uint, tagName: age
fieldValue: [GO Java Python], type: slice, tagName: lang_list
fieldValue: 1e+06, type: float32, tagName: salary
*/