如何在Unmarshal()时允许使用”omitempty”,而在Marshal()时不允许使用”omitempty”?

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

How to allow "omitempty" only Unmarshal() and not when Marshal()?

问题

我有一个结构体:

type MyStruct struct {
  a string `json:"a,omitempty"`
  b int `json:"b"`
  c float64 `json:"c,omitempty"`
}

在进行json.Unmarshal(...)时,如何使字段ac是可选的,但在进行json.Marshal(...)时始终存在于输出的 JSON 中?

英文:

I have a struct:

type MyStruct struct {
  a string `json:"a,omitempty"`
  b int `json:"b"`
  c float64 `json:"c,omitempty"`
}

How would I make the fields a and c optional when doing json.Unmarshal(...), but always present in the output json -- when doing json.Marshal(...)?

答案1

得分: 4

在解组JSON字符串时,您无需担心omitempty。如果JSON输入中缺少属性,结构成员将被设置为其零值。

但是,您需要导出结构的成员(使用A而不是a)。

您可以在以下链接中找到示例代码:https://play.golang.org/p/vRs9NOEBZO4

type MyStruct struct {
	A string  `json:"a"`
	B int     `json:"b"`
	C float64 `json:"c"`
}

func main() {
	jsonStr1 := `{"a":"a string","b":4,"c":5.33}`
	jsonStr2 := `{"b":6}`

	var struct1, struct2 MyStruct

	json.Unmarshal([]byte(jsonStr1), &struct1)
	json.Unmarshal([]byte(jsonStr2), &struct2)

	marshalledStr1, _ := json.Marshal(struct1)
	marshalledStr2, _ := json.Marshal(struct2)

	fmt.Printf("Marshalled struct 1: %s\n", marshalledStr1)
	fmt.Printf("Marshalled struct 2: %s\n", marshalledStr2)
}

您可以在输出中看到,对于struct2,成员A和C会得到它们的零值(空字符串,0)。结构定义中没有出现omitempty,因此您会在JSON字符串中得到所有成员:

Marshalled struct 1: {"a":"a string","b":4,"c":5.33}
Marshalled struct 2: {"a":"","b":6,"c":0}

如果您想区分A是空字符串和A是null/undefined,那么您的成员变量应该是*string而不是string

type MyStruct struct {
	A *string `json:"a"`
	B int     `json:"b"`
	C float64 `json:"c"`
}

func main() {
	jsonStr1 := `{"a":"a string","b":4,"c":5.33}`
	jsonStr2 := `{"b":6}`

	var struct1, struct2 MyStruct

	json.Unmarshal([]byte(jsonStr1), &struct1)
	json.Unmarshal([]byte(jsonStr2), &struct2)

	marshalledStr1, _ := json.Marshal(struct1)
	marshalledStr2, _ := json.Marshal(struct2)

	fmt.Printf("Marshalled struct 1: %s\n", marshalledStr1)
	fmt.Printf("Marshalled struct 2: %s\n", marshalledStr2)
}

现在输出更接近输入:

Marshalled struct 1: {"a":"a string","b":4,"c":5.33}
Marshalled struct 2: {"a":null,"b":6,"c":0}
英文:

You don't need to worry about omitempty when unmarshalling a JSON string. The struct member will get set to its zero value if the attribute is missing from the JSON input.

You do however need to export your struct's members (use A, not a).

go playground: https://play.golang.org/p/vRs9NOEBZO4

type MyStruct struct {
	A string  `json:"a"`
	B int     `json:"b"`
	C float64 `json:"c"`
}

func main() {
	jsonStr1 := `{"a":"a string","b":4,"c":5.33}`
	jsonStr2 := `{"b":6}`

	var struct1, struct2 MyStruct

	json.Unmarshal([]byte(jsonStr1), &struct1)
	json.Unmarshal([]byte(jsonStr2), &struct2)

	marshalledStr1, _ := json.Marshal(struct1)
	marshalledStr2, _ := json.Marshal(struct2)

	fmt.Printf("Marshalled struct 1: %s\n", marshalledStr1)
	fmt.Printf("Marshalled struct 2: %s\n", marshalledStr2)
}

You can see in the output that for struct2, members A and C get their zero values (empty string, 0). omitempty isn't present in the struct definition, so you get all the members in the json string:

Marshalled struct 1: {"a":"a string","b":4,"c":5.33}
Marshalled struct 2: {"a":"","b":6,"c":0}

If you are looking to distinguish between A being an empty string and A being null/undefined, then you'll want your member variable to be a *string, not a string:

type MyStruct struct {
	A *string `json:"a"`
	B int     `json:"b"`
	C float64 `json:"c"`
}

func main() {
	jsonStr1 := `{"a":"a string","b":4,"c":5.33}`
	jsonStr2 := `{"b":6}`

	var struct1, struct2 MyStruct

	json.Unmarshal([]byte(jsonStr1), &struct1)
	json.Unmarshal([]byte(jsonStr2), &struct2)

	marshalledStr1, _ := json.Marshal(struct1)
	marshalledStr2, _ := json.Marshal(struct2)

	fmt.Printf("Marshalled struct 1: %s\n", marshalledStr1)
	fmt.Printf("Marshalled struct 2: %s\n", marshalledStr2)
}

Output is now closer to the input:

Marshalled struct 1: {"a":"a string","b":4,"c":5.33}
Marshalled struct 2: {"a":null,"b":6,"c":0}

huangapple
  • 本文由 发表于 2021年11月19日 02:59:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/70025330.html
匿名

发表评论

匿名网友

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

确定