英文:
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(...)
时,如何使字段a
和c
是可选的,但在进行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}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论