Skip to content

Instantly share code, notes, and snippets.

@tanaikech
Last active April 15, 2021 01:28
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save tanaikech/ada603db41ef0724a2e3d74cc392d9ed to your computer and use it in GitHub Desktop.
Save tanaikech/ada603db41ef0724a2e3d74cc392d9ed to your computer and use it in GitHub Desktop.
Copying Values from JSON to Struct using reflect Package for Golang

Copying Values from JSON to Struct using reflect Package

This is a sample script for copying values from JSON to a struct using reflect package.

Script :

package main

import (
	"encoding/json"
	"fmt"
	"reflect"
)

type obj struct {
	Key1 string `json:"k1"`
	Key2 string `json:"k2"`
	Key3 int64  `json:"k3"`
	Key4 int    `json:"k4"`
	Key5 bool   `json:"k5"`
}

func main() {
	data := `{"k1": "v1", "k2": "v2", "k3": 1234567890, "k4": 456, "k5": true}`
	d := map[string]interface{}{}
	json.Unmarshal([]byte(data), &d)
	obj := &obj{}
	s := reflect.ValueOf(obj).Elem()
	typeOfT := s.Type()
	for i := 0; i < s.NumField(); i++ {
		for j, f := range d {
			if typeOfT.Field(i).Tag.Get("json") == j {
				fl := s.FieldByName(typeOfT.Field(i).Name)
				switch fl.Kind() {
				case reflect.Bool:
					fl.SetBool(f.(bool))
				case reflect.Int, reflect.Int64:
					c, _ := f.(float64)
					fl.SetInt(int64(c))
				case reflect.String:
					fl.SetString(f.(string))
				}
			}
		}
	}
	fmt.Printf("%+v\n", obj) // &{Key1:v1 Key2:v2 Key3:1234567890 Key4:456 Key5:true}
}

Result :

&{Key1:v1 Key2:v2 Key3:1234567890 Key4:456 Key5:true}

The Go Playground

https://play.golang.org/p/Rz-GNbFyDfh

@chenyunda218
Copy link

chenyunda218 commented Mar 14, 2021

Why need the nested loop? I tried directly fetch value of map and got the same output.

	for i := 0; i < s.NumField(); i++ {
		v, err := d[typeOfT.Field(i).Tag.Get("json")]
		if err {
			fl := s.FieldByName(typeOfT.Field(i).Name)
			switch fl.Kind() {
			case reflect.Bool:
				fl.SetBool(v.(bool))
			case reflect.Int, reflect.Int64:
				c, _ := v.(float64)
				fl.SetInt(int64(c))
			case reflect.String:
				fl.SetString(v.(string))
			}
		}
	}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment