go - 解组多种类型的 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"`
}
有人能帮我吗?如何获取参数列表?
解决方案
脚本属性是数组,其中第一项是结构,第二项是字符串。选项 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 本身是否可以使用单独的可执行文件和 args 进行结构化,这样 yaml 看起来也更具可读性。如果没有,那么上述选项应该会有所帮助。
推荐阅读
- java - 使用 Java Spring JPA 和 crud 更新数据库记录
- java - 当指定的应用程序在前台时运行代码
- php - 在 Woocommerce 单一产品页面中移动库存可用性位置
- android - 如何阻止 Flowable 发射更多项目
- swift - WatchOS 上的 SwiftUI 应用程序中是否可以进行基于页面的导航?
- c# - WPF generic.xaml 找不到文件
- php - 当某些输入可能丢失时,将真值表转换为 PHP 代码
- c - -pthreads 库的不同行为
- c# - 在 c# 中使用泛型类型的多种类型列表
- neuroph - 如何为 NeurophStudio 修改 JDK 的路径