英文:
Custom unmarshalling json combining two fields
问题
我有一些 JSON 数据,我想要将其解析成以下结构体:
type Activity struct {
Start time.Time `json:"start"`
End time.Time `json:"end"`
}
如果 JSON 格式正确,那么解析是没有问题的。
然而,有时候 "end" 字段存在,但是只是一个空字符串:
{
"start": "2020-06-02T07:48:35.911Z",
"end": ""
}
在这种情况下,我想要将 Activity.End 设置为 Activity.Start。
我是否可以通过实现 UnmarshalJSON 来实现这个功能,还是必须使用一个 map?
英文:
I have some json I want to unmarshal into the following struct
type Activity struct {
Start time.Time `json:"start"`
End time.Time `json:"end"`
}
Works fine if the json is properly formated.
However, sometimes the "end" fields exists but is just an empty string
{
"start": "2020-06-02T07:48:35.911Z",
"end":""
}
In this case I want Activity.End = Activity.Start
Is there anyway I can do this by implementing UnmarshalJSON or do I have to use a map?
答案1
得分: 1
根据mkopriva的建议:
package main
import (
"encoding/json"
"fmt"
"time"
)
type Activity struct {
Start time.Time `json:"start"`
End time.Time `json:"end"`
}
func (a *Activity) UnmarshalJSON(data []byte) error {
var v struct {
Start time.Time
End json.RawMessage
}
if err := json.Unmarshal(data, &v); err != nil {
return err
}
if len(v.End) > 0 && string(v.End) != `""` {
a.Start = v.Start
return json.Unmarshal([]byte(v.End), &a.End)
}
a.Start = v.Start
a.End = v.Start
return nil
}
func main() {
var data1 = []byte(`{"start": "2020-06-02T07:48:35.911Z","end":"2021-10-15T07:48:35.911Z"}`)
var data2 = []byte(`{"start": "2020-06-02T07:48:35.911Z","end":""}`)
var a Activity
if err := json.Unmarshal(data1, &a); err != nil {
panic(err)
}
fmt.Printf("%+v\n", a)
if err := json.Unmarshal(data2, &a); err != nil {
panic(err)
}
fmt.Printf("%+v\n", a)
}
输出结果:
{Start:2020-06-02 07:48:35.911 +0000 UTC End:2021-10-15 07:48:35.911 +0000 UTC}
{Start:2020-06-02 07:48:35.911 +0000 UTC End:2020-06-02 07:48:35.911 +0000 UTC}
英文:
Based on suggestion of mkopriva:
package main
import (
"encoding/json"
"fmt"
"time"
)
type Activity struct {
Start time.Time `json:"start"`
End time.Time `json:"end"`
}
func (a *Activity) UnmarshalJSON(data []byte) error {
var v struct {
Start time.Time
End json.RawMessage
}
if err := json.Unmarshal(data, &v); err != nil {
return err
}
if len(v.End) > 0 && string(v.End) != `""` {
a.Start = v.Start
return json.Unmarshal([]byte(v.End), &a.End)
}
a.Start = v.Start
a.End = v.Start
return nil
}
func main() {
var data1 = []byte(`{"start": "2020-06-02T07:48:35.911Z","end":"2021-10-15T07:48:35.911Z"}`)
var data2 = []byte(`{"start": "2020-06-02T07:48:35.911Z","end":""}`)
var a Activity
if err := json.Unmarshal(data1, &a); err != nil {
panic(err)
}
fmt.Printf("%+v\n", a)
if err := json.Unmarshal(data2, &a); err != nil {
panic(err)
}
fmt.Printf("%+v\n", a)
}
Output:
{Start:2020-06-02 07:48:35.911 +0000 UTC End:2021-10-15 07:48:35.911 +0000 UTC}
{Start:2020-06-02 07:48:35.911 +0000 UTC End:2020-06-02 07:48:35.911 +0000 UTC}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论