Golang将JSON映射到结构体

huangapple go评论118阅读模式
英文:

Golang map json to struct

问题

我有一个JSON,我需要使用一个结构体来提取其中的数据:

我试图将其映射到以下结构体:

type Message struct {
    Name   string `json:"name"`
    Values []struct {
        Value int `json:"value,omitempty"`
        Comments int `json:"comments,omitempty"`
        Likes    int `json:"likes,omitempty"`
        Shares   int `json:"shares,omitempty"`
    } `json:"values"`
}

这是我的JSON:

[{
        "name": "organic_impressions_unique",
        "values": [{
            "value": 8288
        }]
    }, {
        "name": "post_story_actions_by_type",
        "values": [{
            "shares": 234,
            "comments": 838,
            "likes": 8768
        }]
    }]

我的问题是:

  1. 如何构建我的结构体?
  2. 如何读取name、values和comments?

到目前为止,我无法使用以下代码读取数据:

msg := []Message{}
getJson("https://json.url", msg)
println(msg[0])

getJson函数如下:

func getJson(url string, target interface{}) error {
    r, err := myClient.Get(url)
    if err != nil {
        return err
    }
    defer r.Body.Close()

    return json.NewDecoder(r.Body).Decode(target)
}
英文:

I have a JSON which I need to extract the data out of it using a struct:

I am trying to map it to the below struct:

type Message struct {
    Name   string `json:"name"`
    Values []struct {
        Value int `json:"value,omitempty"`
        Comments int `json:"comments,omitempty"`
        Likes    int `json:"likes,omitempty"`
        Shares   int `json:"shares,omitempty"`
    } `json:"values"`
}

This is my json:

[{
        "name": "organic_impressions_unique",
        "values": [{
            "value": 8288
        }]
    }, {
        "name": "post_story_actions_by_type",
        "values": [{
            "shares": 234,
            "comments": 838,
            "likes": 8768
        }]
    }]

My questions are:

  1. How to structure my struct?
  2. How to read the name, values and comments?

So far I couldn't read the data using the below code:

msg := []Message{}
getJson("https://json.url", msg)
println(msg[0])

the getJson function:

func getJson(url string, target interface{}) error {
    r, err := myClient.Get(url)
    if err != nil {
        return err
    }
    defer r.Body.Close()

    return json.NewDecoder(r.Body).Decode(target)
}

答案1

得分: 16

你的结构是正确的。你只需要使用json.Unmarshal函数和一个正确的目标对象(Message实例的切片:[]Message{})来解析JSON数据。

正确的解析

type Message struct {
    Name   string `json:"name"`
    Values []struct {
        Value    int `json:"value,omitempty"`
        Comments int `json:"comments,omitempty"`
        Likes    int `json:"likes,omitempty"`
        Shares   int `json:"shares,omitempty"`
    } `json:"values"`
}

func main() {
    input := []byte(`
    [{
        "name": "organic_impressions_unique",
        "values": [{
            "value": 8288
        }]
    }, {
        "name": "post_story_actions_by_type",
        "values": [{
            "shares": 234,
            "comments": 838,
            "likes": 8768
        }]
    }]
    `)

    messages := []Message{} // Message实例的切片
    json.Unmarshal(input, &messages)
    fmt.Println(messages)
}
英文:

Your struct is correct. All you need is <s>love</s> to use json.Unmarshal function with a correct target object which is slice of Message instances: []Message{}

Correct unmarshaling:

type Message struct {
    Name   string `json:&quot;name&quot;`
	Values []struct {
    	Value    int `json:&quot;value,omitempty&quot;`
	    Comments int `json:&quot;comments,omitempty&quot;`
		Likes    int `json:&quot;likes,omitempty&quot;`
    	Shares   int `json:&quot;shares,omitempty&quot;`
	} `json:&quot;values&quot;`
}

func main() {
    input := []byte(`
[{
    &quot;name&quot;: &quot;organic_impressions_unique&quot;,
    &quot;values&quot;: [{
        &quot;value&quot;: 8288
    }]
    }, {
        &quot;name&quot;: &quot;post_story_actions_by_type&quot;,
        &quot;values&quot;: [{
            &quot;shares&quot;: 234,
            &quot;comments&quot;: 838,
            &quot;likes&quot;: 8768
        }]
    }]
`)

	messages := []Message{} // Slice of Message instances
    json.Unmarshal(input, &amp;messages)
	fmt.Println(messages)
}

答案2

得分: 3

你的JSON似乎是一个数组。只需将其解组为切片即可。类似这样的代码:

var messages []Message
err := json.Unmarshal(json, &messages)

应该可以工作。

英文:

Your JSON seems to be an array. Just unmarshall it to a slice. Something like:

var messages []Message
err := json.Unmarshal(json, &amp;messages)

Should work.

答案3

得分: 0

我不知道现在是否有帮助,但我最近编写了一个从JSON输入生成精确Go类型的实用程序:https://github.com/m-zajac/json2go

对于第一个帖子中的JSON,它生成了以下结构体:

type Object struct {
    Name   string `json:"name"`
    Values []struct {
        Comments *int `json:"comments,omitempty"`
        Likes    *int `json:"likes,omitempty"`
        Shares   *int `json:"shares,omitempty"`
        Value    *int `json:"value,omitempty"`
    } `json:"values"`
}

你可以像这样将数据解码到这个结构体中:

var docs []Object
if err := json.Unmarshal(input, &docs); err != nil {
    // 处理错误
}
英文:

I don't know if this will be any help now, but i've recently written utility for generating exact go type from json input: https://github.com/m-zajac/json2go

For json from first post it generates this struct:

type Object struct {
	Name	string	`json:&quot;name&quot;`
	Values	[]struct {
		Comments	*int	`json:&quot;comments,omitempty&quot;`
		Likes		*int	`json:&quot;likes,omitempty&quot;`
		Shares		*int	`json:&quot;shares,omitempty&quot;`
		Value		*int	`json:&quot;value,omitempty&quot;`
	}	`json:&quot;values&quot;`
}

You can decode data to this struct like this:

var docs []Object
if err := json.Unmarshal(input, &amp;docs); err != nil {
    // handle error
}

huangapple
  • 本文由 发表于 2017年2月9日 20:28:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/42136765.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定