问题
I'm a new Go programmer (From Java) and I would like to reproduce a generic way which is esay to use in Java.
I want to create some function which allow me to do an Unmarshal on a JSON string in order to avoid code duplicity.
This is my current code which is not working :
type myStruct1 struct {
id string
name string
}
func (obj myStruct1) toString() string {
var result bytes.Buffer
result.WriteString("id : ")
result.WriteString(obj.id)
result.WriteString("\n")
result.WriteString("name : ")
result.WriteString(obj.name)
return result.String()
}
func main() {
content := `{id:"id1",name="myName"}`
object := myStruct1{}
parseJSON(content, object)
fmt.Println(object.toString())
}
func parseJSON(content string, object interface{}) {
var parsed interface{}
json.Unmarshal([]byte(content), &parsed)
}
This code, on run, returns me this :
id :
name :
Do you have any idea ?
Thanks
回答1:
The issue is you want to write to a generic type? You probably want a string map. This works with BSON anyways:
var anyJson map[string]interface{}
json.Unmarshal(bytes, &anyJson)
You'll be able to access the fields like so:
anyJson["id"].(string)
Don't forget to type assert your values, and they must be the correct type or they'll panic. (You can read more about type assertions on the golang site)
回答2:
You have to export your fields:
type myStruct1 struct {
Id string
Name string
}
See Exported Identifiers from documentation.
回答3:
There are a few changes you need to make in your code to make it work:
- The function
json.Unmarshal
can only set variables inside your struct which are exported, that is, which start with capital letters. Use something likeID
andName
for your variable names insidemyStruct1
. - Your content is invalid JSON. What you actually want is
{"ID":"id1","Name":"myName"}
. - You're passing
object
toparseJSON
but you're usingparsed
instead, notobject
. MakeparseJSON
receive a*myStruct
(instead of aninterface{}
), and use that variable instead ofparsed
when unmarshalling the string. Also, always handle the error returns, likeerr := json.Unmarshal(content, object)
, and checkerr
.
I'd suggest you to do the Golang Tour ;)
回答4:
Unmarshal will only set exported fields of the struct.
Which means you need to modify the json struct to use capital case letters:
type myStruct1 struct {
Id string
Name string
}
The reason behind this is that the json library does not have the ability to view fields using reflect unless they are exported.
回答5:
You can also set the file as an Object with dynamic properties inside another struct. This will let you add metadata and you read it the same way.
type MyFile struct {
Version string
Data map[string]interface{}
}
来源:https://stackoverflow.com/questions/36062052/unmarshal-generic-json-in-go