1

I am trying to create a function that takes a []byte and an interface{} (standing for the struct) and returns an interface{} as the struct type passed into the func.

Something like this:

package main

import (

"encoding/json"

)


func UnmarshalFromJSONArray(sms []byte,tt string) (interface{}) {
    var ts = new(tt) 
    err := json.Unmarshal(sms,&ts)
    if(err != nil) {
        fmt.Println(err)
    }
    return sms
}

So that method would run something like this:

// let's say a struct has the following definition:

type MyStructType struct {
    Id int
    Name string
    Desc string
}

// we can some how get its fully qualified class name (this may require reflection?) or pass it into the UnMarshal method direction some how.
mst := "package.MyStructType",

// and then assume a byte array ba that has JSON format for 

ba := []byte(`{"Id":"3","Name":"Jack","Desc":"the man"}`)

stct := UnmarshalFromJSONArray(ba,mst)

MyStructureType out := stct

// leaving "stct" being the unmarshalled byte array which can be used like any other struct of type "MyStructureType"

The key being that I never need to know what the fields of MyStructureType are before unmarshalling. All I need are the name of the struct and some way to instance one and then populate it with JSON byte array data that matches its fields. Hopefully that is possible (it is trivial in java using reflection). So I want to basically unmarshal an anonymous struct type by it's name without needing to know what fields it has.

Any suggestions?

1
  • outstanding edit, thanks! Commented Jan 4, 2014 at 3:57

1 Answer 1

4

The short answer is that this is impossible. There is no string to type translator in Go. You can make a map of strings to reflect.Type's, but you would need to know the possible options ahead of time or you need to provide the caller with a way to register types (perhaps in init).

Assuming you have found a way to resolve the string to its reflect.Type, you can simply call reflect.New(typ).Interface() to get the pointer you need to pass to json.Unmarshal().

The best answer is to avoid trying this all together. Writing idiomatic Java in Go isn't really possible. If I knew more about your problem, I could give you a more idiomatic Go solution.

Sign up to request clarification or add additional context in comments.

2 Comments

Great answer SW, basically i just wanted to be able to pass any struct name (as string) into the UnMarshalFromJSONArray(..) along with a []byte array that has some JSON for fields that may or may not be in that struct name after being instanced, and have it pop out with an instance of the struct with the various fields populated. It would allow me to generically unmarshal JSON data instead of needing to know what struct it was a part of before hand...just looking for code reuse ops. Otherwise I'd make UnMarshal functions for each struct type in my data model which isn't bad but is verbose.
The JSON tutorial here pretty much indicated that the way to do it was as you described but you need to know the field types and you don't get the struct name out of the process, so you need to know that before hand as well...good enough. blog.golang.org/json-and-go

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.