Как разобрать yaml и получить значение для структуры с глубоким интерфейсом - PullRequest
1 голос
/ 06 марта 2019

Я пытаюсь разобрать этот yaml и хочу получить values из записи run (test1 или test2) без успеха, вот мой рабочий пример.

im немного получитьпотерян с картой внутри карты :(, это заданный yaml, который я могу изменить ...

любая идея, как я мог получить эти значения

package main

import (
    "fmt"
    "log"

    "gopkg.in/yaml.v2"
)

var runContent = []byte(`
version: "3.2"

run-parameters:
  before:
    run-parameters:
      run: test1

  after:
    run-parameters:
      run: test2

`)

type FTD struct {
    Version     string     `yaml:"version,omitempty"`
    BuildParams *RunParams `yaml:"run-parameters,omitempty"`
}

type RunParams struct {
    BeforeExec map[string]interface{} `yaml:"before,omitempty"`
    AfterExec map[string]interface{} `yaml:"after,omitempty"`
}

func main() {
    runners := &FTD{}
    // parse mta yaml
    err := yaml.Unmarshal(runContent, runners)
    if err != nil {
        log.Fatalf("Error : %v", err)
    }
    for k, v := range runners.BuildParams.BeforeExec {
        fmt.Println(k, v.(interface{}))
    }
}

Это рабочий пример https://play.golang.org/p/qTqUJy3md0c

также я пытался с

это работает

run := runners.BuildParams.BeforeExec["run-parameters"].(map[interface{}]interface{})["run"]
     fmt.Println("run: ", run)

я пробовал это, что работает, но что происходит, если значение run пустоили нет записи вообще, это вызовет дамп как мне это преодолеть?

1 Ответ

1 голос
/ 06 марта 2019

то, что я пробовал, это то, что работает, но что произойдет, если значение запуска пусто или вообще не будет записи, это вызовет дамп, как я могу преодолеть это?

Вы можете сделать

runParams, ok := runners.BuildParams.BeforeExec["run-parameters"]

if !ok {
    // handle lack of "run-parameters" in BeforeExec
}

runParamsMap, ok := runParams.(map[interface{}]interface{})

if !ok {
    // handle "run-parameters" not being a map
}

run, ok := runParamsMap["run"]

if !ok {
    // handle lack of "run" inside "run-parameters"
}

runStr, ok := run.(string)

if !ok {
    // handle "run" not being a string
}

fmt.Println("run: ", runStr)

Это довольно многословно, поэтому вы можете использовать что-то вроде https://github.com/jmoiron/jsonq,, где вы можете указать «путь» к желаемому значению, вложенному в несколько уровней карт.Несмотря на название «json», эта библиотека работает с интерфейсом map [string] {}, а не с файлами json.Но учтите, что библиотека, которую вы используете для демонтажа yaml, дает map[interface{}]interface{} вместо map[string]interface{}, и вам придется использовать другую, чтобы она работала с jsonq.

run, err := jsonq.NewQuery(runners.BuildParams.BeforeExec).String("run-parameters", "run")

if err != nil {
    // handle all possible errors in one place
}

fmt.Println("run: ", run)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...