去json unmarshal选项

编程入门 行业动态 更新时间:2024-10-25 10:31:55
本文介绍了去json unmarshal选项的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 试图找到一个简单的解决方案来封送/ unmashaling到下面的结构中:

type Resource struct { Data [] ResourceData`json:data`} 类型ResourceData结构{ Id字符串`json:id`类型字符串`json:type`属性map [string] interface {}`json:attributes`关系map [string]资源`json:relationships`} r:= Resource {} json.Unmarshal(body,& r)

这很好,如果:

body =`{data:[{id:1,type:blah}]}`

不过,我也需要回应:

body =`{data:{id:1,type:blah}}`//注意没有切片

我可以创建一个单独的类型

类型ResourceSingle struct { Data ResourceData`json:data`}

然而,这意味着需要复制我已附加到资源的所有功能,这是可能的。但是,我需要在执行之前找出解开哪种类型,再加上关系部分,每个部分都可以包含数据:[] {}或data {},这样这个想法就不会出现工作。

或者我可以使用

map [string] * json.RawMessage //或类型资源结构{ Data * json.RawMessage`json:data`}

但是,如果以json的形式表达,我怎么知道它是一个片段还是一个节点来提供正确的解构结构?

我最后的手段是将umarshal放入map [string]接口并使用大量的反射测试..但是这是非常长的时间。

想法?

亲切的问候,jJ

解决方案

有很多方法来构造它,但最简单的技术归结为实现 json.Unmarshaler ,并检查数据的类型。您可以最小化解析json字节,通常只是第一个字符,或者您可以尝试解组到每个类型并返回成功。

我们将使用后一种技术,并将ResourceData插入切片,而不管输入数据的格式如何,所以我们可以始终以相同的方式对它进行操作:

类型资源结构{ Data [] ResourceData } func(r * Resource)UnmarshalJSON(b []字节)错误{ //这给了我们一个临时的位置以解密为m:= struct { DataSlice struct { Data [] ResourceData`json:data`} DataStruct struct { Data ResourceData`json:data`} } {} //尝试用片段解组数据 err: = json.Unmarshal(b,& m.DataSlice) if err == nil { log.Println(got slice) r.Data = m.DataSlice.Data return nil } else if err,ok:= err。(* json.UnmarshalTypeError); !ok { //除了发生类型错误之外的其他东西 return err } //尝试使用struct 解包数据err = json.Unmarshal(b,& m.DataStruct) if err!= nil { return err } log.Println(got struct) r.Data = append(r.Data,m.DataStruct.Data) return nil }

play.golang/p/YIPeYv4AfT

Trying to find a simple solution to marshaling/unmashaling into the following struct

type Resource struct { Data []ResourceData `json:"data"` } type ResourceData struct { Id string `json:"id"` Type string `json:"type"` Attributes map[string]interface{} `json:"attributes"` Relationships map[string]Resource `json:"relationships"` } r := Resource{} json.Unmarshal(body, &r)

this is great if:

body = `{"data":[{"id":"1","type":"blah"}]}`

However I also need it to respond to:

body = `{"data":{"id":"1","type":"blah"}}` //notice no slice

I could make a separate type

type ResourceSingle struct { Data ResourceData `json:"data"` }

However, that would mean needing to duplicate all the functions I have attached to resource, which is possible. However, i would need to find out which type to unmarshal into before executing it, plus when it comes to the relationships part, each of those could contain data:[]{} or data{}, so that idea isn't going to work.

Alternatively I could use

map[string]*json.RawMessage //or type Resource struct { Data *json.RawMessage `json:"data"` }

but still, when in json form how do I know if it is a slice or a node to supply the correct struct to unmarshal into?

My last resort is to umarshal into map[string]interface and use lots of reflect testing .. but this is very long winded.

Ideas?

Kind regards, jJ

解决方案

There's a number of ways to structure it, but the simplest technique comes down to implementing a json.Unmarshaler, and inspecting the type of the data. You can minimally parse the json bytes, often just the first character, or you can try to unmarshal into each type and return the one that succeeds.

We'll use the latter technique here, and insert the ResourceData into a slice regardless of the incoming data's format, so we can always operate on it in the same manner:

type Resource struct { Data []ResourceData } func (r *Resource) UnmarshalJSON(b []byte) error { // this gives us a temporary location to unamrshal into m := struct { DataSlice struct { Data []ResourceData `json:"data"` } DataStruct struct { Data ResourceData `json:"data"` } }{} // try to unmarshal the data with a slice err := json.Unmarshal(b, &m.DataSlice) if err == nil { log.Println("got slice") r.Data = m.DataSlice.Data return nil } else if err, ok := err.(*json.UnmarshalTypeError); !ok { // something besides a type error occurred return err } // try to unamrshal the data with a struct err = json.Unmarshal(b, &m.DataStruct) if err != nil { return err } log.Println("got struct") r.Data = append(r.Data, m.DataStruct.Data) return nil }

play.golang/p/YIPeYv4AfT

更多推荐

去json unmarshal选项

本文发布于:2023-11-15 08:01:25,感谢您对本站的认可!
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:选项   json   unmarshal

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!