This page looks best with JavaScript enabled

Go reflection

 ·  🎃 kr0m

Reflection is the ability of a program to inspect the types and values of variables at runtime. This can be interesting for generating generic code in the same way that happens when we use interfaces , although I honestly believe its greatest utility is for debugging potential code issues.


If you are new to the world of Go, I recommend the following previous articles:


Reflection package:

The reflection package offers several interesting methods that allow us to analyze the types and values of our variables data. The best way to see this is through an example.

package main

import (
    "fmt"
    "reflect"
)

type order struct {
    ordId      int
    customerId int
}

type employee struct {
    name    string
    id      int
    address string
    salary  int
    country string
}

func main() {
    o := order{
        ordId:      456,
        customerId: 56,
    }

    e := employee{
        name:    "Naveen",
        id:      565,
        address: "Coimbatore",
        salary:  90000,
        country: "India",
    }

    fmt.Println("o ValueOf.Kind: ", reflect.ValueOf(o).Kind())
    fmt.Println("o TypeOf.Kind: ", reflect.TypeOf(o).Kind())
    fmt.Println("o TypeOf.Name: ", reflect.TypeOf(o).Name())
    fmt.Println("o ValueOf.NumField: ", reflect.ValueOf(o).NumField())

    for i := 0; i < reflect.ValueOf(o).NumField(); i++ {
        switch reflect.ValueOf(o).Field(i).Kind() {
        case reflect.Int:
            fmt.Printf("%v -> Int: %d\n", reflect.TypeOf(o).Field(i).Name, reflect.ValueOf(o).Field(i).Int())
        case reflect.String:
            fmt.Printf("%v -> String: %s\n", reflect.TypeOf(o).Field(i).Name, reflect.ValueOf(o).Field(i).String())
        default:
            fmt.Println("Unsupported type.")
        }
    }

    fmt.Println("---------")

    fmt.Println("e ValueOf.Kind: ", reflect.ValueOf(e).Kind())
    fmt.Println("e TypeOf.Kind: ", reflect.TypeOf(e).Kind())
    fmt.Println("e TypeOf.Name: ", reflect.TypeOf(e).Name())
    fmt.Println("e ValueOf.NumField: ", reflect.ValueOf(e).NumField())

    for i := 0; i < reflect.ValueOf(e).NumField(); i++ {
        switch reflect.ValueOf(e).Field(i).Kind() {
        case reflect.Int:
            fmt.Printf("%v -> Int: %d\n", reflect.TypeOf(e).Field(i).Name, reflect.ValueOf(e).Field(i).Int())
        case reflect.String:
            fmt.Printf("%v -> String: %s\n", reflect.TypeOf(e).Field(i).Name, reflect.ValueOf(e).Field(i).String())
        default:
            fmt.Println("Unsupported type.")
        }
    }
}
o ValueOf.Kind:  struct
o TypeOf.Kind:  struct
o TypeOf.Name:  order
o ValueOf.NumField:  2
ordId -> Int: 456
customerId -> Int: 56
---------
e ValueOf.Kind:  struct
e TypeOf.Kind:  struct
e TypeOf.Name:  employee
e ValueOf.NumField:  5
name -> String: Naveen
id -> Int: 565
address -> String: Coimbatore
salary -> Int: 90000
country -> String: India
If you liked the article, you can treat me to a RedBull here