解析地图Yaml错误

时间:2018-08-18 10:16:48

标签: go struct yaml

我有以下程序需要解析yaml 具有以下结构

https://codebeautify.org/yaml-validator/cbabd352 这是有效的Yaml ,我使用字节来使其更简单 也许在复制粘贴到问题的过程中缩进已更改,但是您可以在链接中看到yaml有效

Yaml具有api_version 和跑步者,对于每个跑步者(键是名称),我都有命令列表 并且我需要为function1function4打印这些命令,我​​在这里做错了什么?

package main

import (
    "fmt"
    "log"

    "gopkg.in/yaml.v2"
)

var runContent = []byte(`
api_ver: 1
runners:
 - name: function1
   type:
    - command: spawn child process
    - command: build
    - command: gulp
 - name: function2
   type:
    - command: run function 1
 - name: function3
   type:
    - command: ruby build
 - name: function4
   type:
    - command: go build
`)

type Result struct {
    Version string    `yaml:"api_ver"`
    Runners []Runners `yaml:"runners"`
}

type Runners struct {
    Name string    `yaml:"name"`
    Type []Command `yaml:"type"`
}

type Command struct {
    Command string `yaml:"command"`
}

func main() {

    var runners []Result
    err := yaml.Unmarshal(runContent, &runners)
    if err != nil {
        log.Fatalf("Error : %v", err)
    }
    fmt.Printf("%+v", runners[0])
}

我得到cannot unmarshal !!map into []main.Result

的错误

我无法更改Yaml,应该完全像这样

https://codebeautify.org/yaml-validator/cbabd352

这是代码 https://play.golang.org/p/zidjOA6-gc7

1 个答案:

答案 0 :(得分:0)

您提供的Yaml包含令牌错误。在https://codebeautify.org/yaml-validator/cbaabb32

处验证代码中使用的Yaml

之后,创建结构类型的变量结果不是数组。因为您使用的Yaml正在使用Runners数组和api_version创建结构。

var runners []Result

应该是

var runners Result

因为该结构不是切片。为yaml中使用的功能名称获取命令列表。您需要遍历runners数组以查找函数名称并获取该函数的命令值。 下面是工作代码:

package main

import (
    "fmt"
    "log"

    "gopkg.in/yaml.v2"
)

var runContent = []byte(`
api_ver: 1
runners:
  - name: function1
    type:
    - command: spawn child process
    - command: build
    - command: gulp
  - name: function2
    type:
    - command: run function 1
    - name: function3
    type:
    - command: ruby build
  - name: function4
    type:
  - command: go build
`)

type Result struct {
    Version string    `yaml:"api_ver"`
    Runners []Runners `yaml:"runners"`
}

type Runners struct {
    Name string    `yaml:"name"`
    Type []Command `yaml:"type"`
}

type Command struct {
    Command string `yaml:"command"`
}

func main() {

    var runners Result
    // parse mta yaml
    err := yaml.Unmarshal(runContent, &runners)
    if err != nil {
        log.Fatalf("Error : %v", err)
    }
    commandList := getCommandList("function1", runners.Runners)
    fmt.Printf("%+v", commandList)
}

func getCommandList(name string, runners []Runners) []Command {
    var commandList []Command
    for _, value := range runners {
        if value.Name == name {
            commandList = value.Type
        }
    }
    return commandList
}

Playground example