~/snippets/go-compare-structs-with-reflect
Published on

Compare structs with reflect

525 words3 min read
package main

import (
	"fmt"
	"reflect"
)

type Custom struct {
	Wibble string
	Wobble string
}

type AnotherCustom struct {
	Jibble string
	Jobble string
}

type Test struct {
	A []string
	B []int
	C []bool
	D []Custom
	E []AnotherCustom
}

func main() {
	primary := &Test{
		A: []string{"a", "b", "c", "d"},
		B: []int{1, 2, 3, 4},
		D: []Custom{{Wibble: "hello", Wobble: "world"}},
		E: []AnotherCustom{{Jibble: "goodbye", Jobble: "mars"}},
	}

	secondary := &Test{
		A: []string{"a", "b", "c"},
		B: []int{1, 2, 3, 4},
		D: []Custom{{Wibble: "hello", Wobble: "world"}},
		E: []AnotherCustom{{Jibble: "aaaaaaahhhhhhhh", Jobble: "it's so hot"}},
	}

	v := reflect.ValueOf(primary).Elem()
	sf := reflect.Indirect(reflect.ValueOf(secondary))

	for i := 0; i < v.NumField(); i++ {
		tf := v.Type().Field(i)

		val := v.Field(i)
		ov := sf.FieldByName(tf.Name)

		if !reflect.DeepEqual(val.Interface(), ov.Interface()) {
			fmt.Printf("%s does not match \n", tf.Name)
		} else {
			fmt.Printf("%s does match \n", tf.Name)
		}

	}
}