在 Go 中解析 JSON 时如何指定默认值

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30445479/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 17:54:42  来源:igfitidea点击:

How to specify default values when parsing JSON in Go

jsongo

提问by JW.

I want to parse a JSON object in Go, but want to specify default values for fields that are not given. For example, I have the struct type:

我想在 Go 中解析一个 JSON 对象,但想为未给出的字段指定默认值。例如,我有结构类型:

type Test struct {
    A string
    B string
    C string
}

The default values for A, B, and C, are "a", "b", and "c" respectively. This means that when I parse the json:

A、B 和 C 的默认值分别为“a”、“b”和“c”。这意味着当我解析 json 时:

{"A": "1", "C": 3}

I want to get the struct:

我想得到结构:

Test{A: "1", B: "b", C: "3"}

Is this possible using the built-in package encoding/json? Otherwise, is there any Go library that has this functionality?

这可以使用内置包encoding/json吗?否则,是否有任何具有此功能的 Go 库?

回答by JW.

This is possible using encoding/json: when calling json.Unmarshal, you do not need to give it an empty struct, you can give it one with default values.

这可以使用 encoding/json:调用时json.Unmarshal,您不需要给它一个空结构,您可以给它一个带有默认值的结构。

For your example:

对于您的示例:

var example []byte = []byte(`{"A": "1", "C": "3"}`)

out := Test{
    A: "default a",
    B: "default b",
    // default for C will be "", the empty value for a string
}
err := json.Unmarshal(example, &out) // <--
if err != nil {
    panic(err)
}
fmt.Printf("%+v", out)

Running this example in the Go playgroundreturns {A:1 B:default b C:3}.

在 Go 游乐场中运行此示例返回{A:1 B:default b C:3}.

As you can see, json.Unmarshal(example, &out)unmarshals the JSON into out, overwriting the values specified in the JSON, but leaving the other fields unchanged.

如您所见,json.Unmarshal(example, &out)将 JSON 解组为out,覆盖 JSON 中指定的值,但保持其他字段不变。

回答by Christian

In case u have a list or map of Teststructs the accepted answer is not possible anymore but it can easily be extended with a UnmarshalJSON method:

如果您有Test结构的列表或映射,则不再可能接受已接受的答案,但可以使用 UnmarshalJSON 方法轻松扩展它:

func (t *Test) UnmarshalJSON(data []byte) error {
  type testAlias Test
  test := &testAlias{
    B: "default B",
  }

  _ = json.Unmarshal(data, test)

  *t = Test(*test)
  return nil
}

The testAlias is needed to prevent recursive calls to UnmarshalJSON. This works because a new type has no methods defined.

需要 testAlias 来防止对 UnmarshalJSON 的递归调用。这是有效的,因为新类型没有定义方法。

https://play.golang.org/p/qiGyjRbNHg

https://play.golang.org/p/qiGyjRbNHg