Passing a struct to a function

Hi,

I’m fairly new to Go so what I’m trying to do might be wrong.

I’m attempting to extract the data I need from a number of JSON documents, using a struct as the source of truth. I want to be able to use the struct type to find the file. The end object needs to be the json fields that match the corresponding struct.

In the same directory I have the set of gzipped json documents.

package main

import (
	"compress/gzip"
	"encoding/json"
	"fmt"
	"io"
	"os"
	"reflect"
	"strings"
)

// user.json.gz
// {
//   "Name": "Ted",
//   "Email": "ted@t.com",
//   "Password": "tedw1ns"
// }

// animals.json.gz
// {
//   "Type": "Dog",
//   "Breed": "Whippet",
//   "Age": "4"
// }

type CollectionsType struct {
	User    []UserType
	Animals []AnimalsType
}

type UserType struct {
	Name  string `json:"Name"`
	Email string `json:Email"`
}

type AnimalsType struct {
	Type  string `json:"Type"`
	Breed string `json:"Breed"`
}

func main() {

	// Get a list of collections
	// from the CollectionsType
	var collectionsToProcess []string
	t := reflect.TypeOf(CollectionsType{})
	for i := 0; i < t.NumField(); i++ {
		field := t.Field(i)
		collectionsToProcess = append(collectionsToProcess, field.Name)
	}

	// Find the files and process
	for _, c := range collectionsToProcess {
		file := strings.ToLower(c) + ".json.gz"
		f, err := os.Open(file)
		if err != nil {
			fmt.Println(err)
		}
		defer f.Close()

		// I want to be able to pass the uncompressed stream here
		// and the corresponding struct so that we end up with only the defined fields.
		j := decodeJ(f, c)
		fmt.Println(j)
	}
}

func decodeJ(r io.Reader, v interface{}) error {
	raw, err := gzip.NewReader(r)
	if err != nil {
		return err
	}

	return json.NewDecoder(raw).Decode(&v)
}

Hopefully it will make sense to somebody who can point me in the right direction.

Cheers in advance,
Rob

I’d have done it with a couple of factory functions or similar instead of reflect, but continuing along your chosen path:

https://play.golang.org/p/blsOhhCIIjh

You can’t look up a type by name at runtime in Go, so I created an explicit map for it instead.

1 Like

Hi Jakob,

Many thanks for this, I’ve managed to get it working with your code!

I’d be interested to see how you would have done it with the factory functions so I can learn.

Cheers,
Rob

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.