Reflection es la habilidad de un programa de inspeccionar los tipos y valores de las variables en tiempo de ejecución, esto puede resultar interesante para generar código genérico del mismo modo que pasaba cuando utilizábamos interfaces aunque sinceramente creo que su mayor utilidad es para debugear posibles problemas de código.
Si eres nuevo en el mundo de Go te recomiendo los siguientes artÃculos anteriores:
- Go basics
- Go functions
- Go unit tests
- Go pointers
- Go interfaces
- Go structs
- Go generics
- Go errors
- Go routines
- Go strings, chars y runas
- Go defer
- Go first class functions
Paquete reflection:
El paquete reflection ofrece varios métodos interesantes que nos permitirán analizar los tipos y valores de los datos de nuestras variables. La mejor manera de verlo es mediante un ejemplo.
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