解组多个类型的YAML数组



我对Go还是有点陌生,可以使用一些帮助。我有一段YAML,我想把它分解成我可以使用的东西。

YAML:

script:
- executable: python
- script.py

这些是我目前拥有的结构体。我能得到Executable,但我不能得到参数列表。

type Config struct {
Script []ScriptConfig `yaml:"script"`
}
type ScriptConfig struct {
Executable string   `yaml:"executable"`
Arguments  []string `yaml:",flow"`
}

有人能帮我吗?我怎样才能得到参数的列表呢?

script属性是数组,其中第一项为结构体,第二项为字符串。选项1:制作ScriptConfig接口,但在解码后,您需要进行类型转换并进一步解码第一个ScriptConfig条目。

type ScriptConfig interface{}
type Config struct {
Script []ScriptConfig `yaml:"script"`
}

选项2:使ScriptConfig成为另一个具有arg和可执行属性的结构体,并使用自定义封送器。然而,你会有一个属性nil,你需要关心,它也不是很干净,从你的实体模型。

type ScriptConfig struct {
Executable string `yaml:"executable"`
Arg string
}
func (s *ScriptConfig) UnmarshalYAML(unmarshal func(interface{}) error) error {
var exec struct {
Executable string `yaml:"executable"`
}
if err := unmarshal(&exec); err != nil {
// will be error for 2nd row onwards
fmt.Println(err)
}
var arg string
if err := unmarshal(&arg); err != nil {
// will be error for 1st row
fmt.Println(err)
}
s.Executable = exec.Executable
s.Arg = arg
return nil
}

选项3:使用yaml.Node和临时结构,并使用自定义封送处理将其转换为您想要的实际结构。这有点复杂,但你得到了清晰的实体模型。

type tmpConfig struct {
// Script []ScriptConfig `yaml:"script"`
Script []yaml.Node `yaml:"script"`
}
type tmpExecutable struct {
Executable string `yaml:"executable"`
}
type ScriptConfig struct {
Executable string
Args       []string
}
type Config struct {
Script ScriptConfig `yaml:"script"`
}
func (c *Config) UnmarshalYAML(v *yaml.Node) error {
var tmp tmpConfig
if err := v.Decode(&tmp); err != nil {
return err
}
l := len(tmp.Script)
if l < 1 {
return nil
}
var tmpexec tmpExecutable
if err := tmp.Script[0].Decode(&tmpexec); err != nil {
return err
}
//copy the executable property from the decoded temp struct
c.Script.Executable = tmpexec.Executable
c.Script.Args = make([]string, l-1)
//copy the args skipping first one
for i := 1; i < len(tmp.Script); i++ {
c.Script.Args[i-1] = tmp.Script[i].Value
}
fmt.Println(c)
return nil
}

一般提示:检查yaml本身是否可以用单独的可执行文件和参数进行结构化,这样yaml看起来也更可读。如果没有,那么上面的选项应该有帮助。

最新更新