# Golang reflect

## 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.

```go
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.

```go
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

```go
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
*/
```
