Golang:具有方法的 JSON 数组

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

golang: json array that has also methods

问题

我有一个像这样的数据结构:

type (
  parent struct {
    Items []*child
  }
  child struct {
    Field string `json:"field"`
  }
)

我还希望parent有一些方法:

func (p *parent) example() { }

然而,JSON的要求是parent只是一个数组:

[
  {
    "field": "data"
  }
]

我希望parent是一个简单的数组,但是为了让parent有方法,它不能是一个数组类型。

有没有一种方法可以用一个数据结构解决这两个问题?

(更复杂的是,我要处理的实际数据结构有两个层级:greatgrandparent包含[]grandparent,而grandparent有一个包含[]childparent。JSON结构是外部定义的,数组没有键名,我希望每个结构体都有方法。)

英文:

I have a data structure like this:

type (
  parent struct {
    Items []*child
  }
  child struct {
    Field string `json:"field"`
  }
)

I also want parent to have methods:

func (p *parent) example() { }

However the json requirement is that parent is just an array:

[
  {
    "field": "data"
  }
]

I want parent to be a simple array, but in order for parent to have methods, it cannot be an array type.

Is there a way to solve both problems with one data structure?

(To make matters more complicated, the actual data structure I have to work with has two levels of this: greatgrandparent contains []grandparent, and grandparent has a parent that contains []child. The json structure is externally defined, the arrays have no key names, and I would like methods on each of the four structs.)

答案1

得分: 1

为了使父类具有方法,它不能是一个数组类型。

它可以是数组类型,只是必须要有一个名称,因为只有有名称的类型(或指向有名称的类型的指针)才能实现方法。以下是有效的Go代码:

type parent []*child

func (p parent) example() { /* ... */ }

请注意,上述的parent是一个切片而不是数组。在Go中,数组具有静态长度,无法扩展或缩小,而切片具有动态长度,可以随意调整大小。数组和切片密切相关但并不相同。


另一种方法是让结构体类型实现json.Unmarshaler/json.Marshaler接口:

type parent struct { Items []*child }

func (p *parent) UnmarshalJSON(data []byte) error {
    return json.Unmarshal(data, &p.Items)
}

func (p parent) MarshalJSON() ([]byte, error) {
    return json.Marshal(p.Items)
}

上述代码将生成所需的JSON结构。

英文:

> in order for parent to have methods, it cannot be an array type.

It can, it just MUST have a name because only named types (or pointers to named types) can implement methods. The following is valid Go code:

type parent []*child

func (p parent) example() { /* ... */ }

Note that the above parent is a slice and not an array. Arrays in Go have static length, you cannot grow them and you cannot shrink them, slices on the other hand have dynamic length and you can resize them at will. Arrays and slices are closely related but not the same.


An alternative would be to have the struct type implement the json.Unmarshaler/json.Marshaler interfaces:

type parent struct { Items []*child }

func (p *parent) UnmarshalJSON(data []byte) error {
    return json.Unmarshal(data, &p.Items)
}

func (p parent) MarshalJSON() ([]byte, error) {
    return json.Marshal(p.Items)
}

The above will produce the required JSON structure.

huangapple
  • 本文由 发表于 2022年12月22日 21:36:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/74889308.html
匿名

发表评论

匿名网友

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

确定