David Saintloth
David Saintloth

Reputation: 4231

Instantiating a struct via name using a string in go

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?

Upvotes: 1

Views: 336

Answers (1)

Stephen Weinberg
Stephen Weinberg

Reputation: 53398

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.

Upvotes: 4

Related Questions