unmarshal generic json in Go

你说的曾经没有我的故事 提交于 2021-02-07 08:45:05

问题


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:

  1. The function json.Unmarshal can only set variables inside your struct which are exported, that is, which start with capital letters. Use something like ID and Name for your variable names inside myStruct1.
  2. Your content is invalid JSON. What you actually want is {"ID":"id1","Name":"myName"}.
  3. You're passing object to parseJSON but you're using parsed instead, not object. Make parseJSON receive a *myStruct (instead of an interface{}), and use that variable instead of parsed when unmarshalling the string. Also, always handle the error returns, like err := json.Unmarshal(content, object), and check err.

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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!