如何在没有任何转换的情况下将前导零作为字符串读取YAML属性?YAML 示例文件:provisioning: devices: 000000001515: properties: example: 30s options: dummy: trueGolang Code - 最小可重现性示例:package mainimport ( "fmt" "github.com/ghodss/yaml")//DeviceSpec devicetype DeviceSpec struct { Properties map[string]string `yaml:"properties,omitempty"` Options map[string]string `yaml:"options,omitempty"`}//Spec provisitype Spec struct { Provisioning struct { Devices map[string]DeviceSpec `yaml:"devices,omitempty"` }}var input = []byte(`provisioning: devices: 000000001515: properties: example: 30s options: dummy: true`)func main() { config := Spec{} if err := yaml.Unmarshal(input, &config); err != nil { panic(err) } for uuid, _ := range config.Provisioning.Devices { fmt.Println(uuid) }}输出845预期输出000000001515溶液问题与我使用的 YAML 包有关。用软件包替换它解决了问题,它工作得很好 - 请参阅下面的评论部分 - 谢谢大家。"github.com/ghodss/yaml" v1.0.0"gopkg.in/yaml.v3"import ( "fmt" "gopkg.in/yaml.v3")
1 回答

天涯尽头无女友
TA贡献1831条经验 获得超9个赞
现在我们发现了错误,让我们对发生的事情进行事后分析:
你使用的库,github.com/ghodss/yaml,说
这个库首先使用go-yaml将YAML转换为JSON,然后使用json。元帅和json。取消元帅以转换为结构或从结构转换。
关于为什么这是一个好主意的链接博客文章消失了,这并没有特别有帮助。无论如何,让我们看看那里的代码实际上做了什么:
var yamlObj interface{} err := yamlUnmarshal(y, &yamlObj)
因此,它采用您的 YAML 输入并将其加载到接口中。当您实际提供目标类型时,这是一个坏主意。这里发生的事情是,go-yaml可以自由选择目标类型,如果是这样,它显然以数字形式读取,前导零作为八进制数。这符合过时的定义!!YAML 1.1 的 int 标记:
[-+]?0[0-7_]+ # (base 8)
但是,它早已被YAML 1.2所取代:
0o [0-7]+ tag:yaml.org,2002:int (Base 8)
go-yaml似乎实现了YAML 1.1规则。这似乎是一个糟糕的决定,可能是偶然完成的,可能需要一个问题报告。
因此,无论如何,当加载 YAML 时,该值将被解释为八进制值。github.com/ghodss/yaml 继续将值分解为JSON,然后再次将其取消元帅,但我们已经输了。
结论是,我认为 github.com/ghodss/yaml 有害的,并建议不要使用它。
- 1 回答
- 0 关注
- 154 浏览
添加回答
举报
0/150
提交
取消