猿问

Unmarshal YAML 文件 - 如何将前导零作为字符串读取 YAML 参数?

如何在没有任何转换的情况下将前导零作为字符串读取YAML属性?


YAML 示例文件:


provisioning:

  devices: 

    000000001515:

        properties: 

          example: 30s

        options:

          dummy: true

Golang Code - 最小可重现性示例:


package main


import (

    "fmt"

    "github.com/ghodss/yaml"

)


//DeviceSpec device

type DeviceSpec struct {

    Properties map[string]string `yaml:"properties,omitempty"`

    Options    map[string]string `yaml:"options,omitempty"`

}


//Spec provisi

type 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"

)


守候你守候我
浏览 155回答 1
1回答

天涯尽头无女友

现在我们发现了错误,让我们对发生的事情进行事后分析:你使用的库,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 有害的,并建议不要使用它。
随时随地看视频慕课网APP

相关分类

Go
我要回答