【发布时间】:2021-09-20 10:50:30
【问题描述】:
当将结构的布尔字段编组为 XML 时,,omitempty 选项对于大多数用途来说不是很有用 - false 是 Go 中布尔变量的零值,正如预期的那样,布尔 ,omitempty 字段与编组时忽略 false 的值。最常建议的解决方案似乎是使用指针来指示值是否存在。这是我对这个想法的基本实现:
package main
import (
"encoding/xml"
"fmt"
)
type Person struct {
XMLName xml.Name `xml:"person"`
IsMarried *bool `xml:"married"` // Required field.
IsRetired *bool `xml:"retired,omitempty"` // Optional field.
}
func boolPointer(b bool) *bool {
return &b
}
func printPersonXml(person Person) {
output, err := xml.MarshalIndent(person, " ", " ")
if err != nil {
fmt.Printf("error: %v\n", err)
} else {
fmt.Println(string(output))
}
}
func main() {
person := Person{
IsMarried: boolPointer(true),
IsRetired: nil,
}
printPersonXml(person)
}
这按预期工作并产生输出
<person>
<married>true</married>
</person>
但是,在这种情况下,,omitempty 选项似乎完全失去了意义。 任何具有nil 值的字段 都不会包含在生成的 XML 代码中。比如我把main()的内容改成
person := Person{
IsMarried: nil,
IsRetired: nil,
}
printPersonXml(person)
输出变成
<person></person>
虽然我更喜欢
<person>
<married></married>
</person>
如 here 所述,这可能是预期的行为:“Marshal 通过编组指针指向的值来处理指针,或者,如果指针为 nil,则不写入任何内容。”
但是,是否可以使用标准 xml 包来实现我的首选行为?如果是,是否需要为其引入新类型和自定义 MarshalXML() 方法?
尽管出于显而易见的原因我在这里关注布尔变量,但我也想将这种方法扩展到其他基本类型的指针。
【问题讨论】: