如何解组 yaml 数组?

How to unmarshal a yaml array?

我有下一个 yaml,如果我在 online yaml website 中验证它,它说它是有效的:

- {"foo": "1", "bar": "2"}

然后,我写了一段代码来解析这个 yaml 中的值 12,如下所示:

test.go:

package main
import "gopkg.in/yaml.v2"
import "fmt"

type Config struct {
    Foo string
    Bar string
}

type Configs struct {
    Cfgs []Config `foobar`
}

func main() {
    //var data = `
    //  foobar:
    //  - foo: 1
    //    bar: 2
    //`
    var data = `
      - foo: 1
        bar: 2
    `

    source := []byte("foobar:" + data)
    var configs Configs
    err := yaml.Unmarshal(source, &configs)
    if err != nil {
        fmt.Println("error: %v", err)
    }
    fmt.Printf("--- configs:\n%v\n\n", configs)
    fmt.Println(configs.Cfgs[0].Foo)
    fmt.Println(configs.Cfgs[0].Bar)
}

它工作正常如下:

shubuntu1@shubuntu1:~/20210810$ go run test.go
--- configs:
{[{1 2}]}

1
2

有什么问题?

你可以看到我在这里做了一个解决方法,在原始 yaml 之前添加特殊的 foobar 键,然后我可以使用 type Configs struct 解组它:

来自

- foo: 1
  bar: 2

foobar:
- foo: 1
  bar: 2

所以,如果我不使用解决方法添加前缀foobar:,我怎么能直接解析- {"foo": 1, "bar": 2}

由于您的 YAML 数据是一个数组,将其解组为 Config 结构的数组。

package main

import (
    "fmt"

    "gopkg.in/yaml.v2"
)

type Config struct {
    Foo string
    Bar string
}

func main() {
    var configs []Config

    var data = `
      - foo: 1
        bar: 2
    `

    err := yaml.Unmarshal([]byte(data), &configs)
    if err != nil {
        panic(err)
    }

    fmt.Println(configs)
}

输出:

[{1 2}]

试穿 - Go Playground

既然问题已经回答了,我想我可以补充一些东西来讨论:

    var data = `
      - foo: 1
        bar: 2
    `

此处的数据变量,按照您的写法,包含每行开头的缩进。

此处的额外缩进将与所有实际的 yaml 数据一起传递到 yaml.Unmarshal(),这可能会造成混乱,因为 gofmt 格式化您的代码以使用 TAB 作为缩进TAB 缩进在 yaml 中被禁止 ().

如果在 yaml 中使用制表符作为缩进,在尝试解组时会抛出这样的错误:

yaml: line 1: found a tab character that violates indentation

您最好从单独的文件中加载 data 以避免此类问题。

package main

import (
    "fmt"
    "io/ioutil"

    "gopkg.in/yaml.v2"
)

type Config struct {
    Foo string
    Bar string
}

func main() {
    var configs []Config

    source, err := ioutil.ReadFile("config.yaml")
    if err != nil {
        fmt.Printf("failed reading config file: %v\n", err)
    }

    err = yaml.Unmarshal(source, &configs)
    if err != nil {
        fmt.Printf("error: %v\n", err)
    }

    fmt.Printf("config:\n%+v\n", configs)
}

config.yaml:

- foo: 1
  bar: 2

输出:

config:
[{Foo:1 Bar:2}]