« Back to Index

[Golang Reflection with Struct]

View original Gist on GitHub

Tags: #go #golang #pointer #struct #reflection #iterate #fields

Iterate over Struct.go

package main

import (
	"fmt"
	"reflect"
)

func main() {
	f := "foo"
	b := "bar"
	
	x := struct {
		Foo *string
		Bar *string
	}{&f, &b}

	// NOTE: pass value as reflect.Indirect(x) if x is a struct pointer
	v := reflect.ValueOf(x)

    // prints the value which is the same as %+v on the struct itself and the type is something like *main.struct{...}
  	fmt.Printf("reflect: %+v (type: %+v)\n", v, v.Type())

	for i := 0; i < v.NumField(); i++ {
	    field := v.Field(i)
      
      	// v.Field == memory address of first struct field
        fmt.Println("Field:", v.Field, v.FieldByIndex([]int{0}), v.FieldByIndex([]int{0}).Addr())
      
	    // .Interface() will panic on unexported field!
   		if !field.CanInterface() {
			continue
		}
      
        if field.Kind() == reflect.Bool {
            // do something with a boolean type field
            // see also: https://golang.org/pkg/reflect/#Kind const iota
          
          	if field.CanSet() {
				field.Set(reflect.ValueOf(true))
			}
        }

      	fmt.Printf("name: %+v, value: %+v (type: %T, kind: %+v)\n",
			v.Type().Field(i).Name, // Name attribute gives us the struct's key
			field.Elem(), 	// Elem() dereferences the pointer value
            field.Interface()), // Interface() provides the interface itself (e.g. {Foo: "foo", Bar: "bar"})
		    field.Kind() // Kind() give back the type of the field
	}
	
	/*
	name: Foo, value: foo (*string)
	name: Bar, value: bar (*string)
	*/
}