我正在尝试将以下YAML数据分解为Go结构。
数据采用以下格式:
fetchers:
- type: "aws"
config:
omega: "lul"
- type: "kubernetes"
config:
foo: "bar"
根据类型字段,我想确定是否将配置字段解组到awsConfig或kubernetesConfig结构中。
我当前的代码如下(使用“gopkg.in/yaml.v2”):
type kubernetesConfig struct {
foo string `yaml:"foo"`
}
type awsConfig struct {
omega string `yaml:"omega"`
}
var c struct {
Fetchers []struct {
Type string `yaml:"type"`
Config interface{} `yaml:"config"`
} `yaml:"fetchers"`
}
err := yaml.Unmarshal(data, &c)
if err != nil {
log.Fatal(err)
}
for _, val := range c.Fetchers {
switch val.Type {
case "kubernetes":
conf := val.Config.(kubernetesConfig)
fmt.Println(conf.foo)
case "aws":
conf := val.Config.(awsConfig)
fmt.Println(conf.omega)
default:
log.Fatalf("No matching type, was type %v", val.Type)
}
}
操场代码:https://go.dev/play/p/klxOoHMCtnG
目前它被解组为 map[接口 {}]接口 {},无法转换为上述结构之一。错误:panic:接口转换:接口 {}
是映射[接口 {}]接口 {},而不是 main.awsConfig
\
我是否必须使用自定义UnmarshalYAML函数实现YAML包的Unmarshaler接口才能完成此操作?
这种类型的任务(您希望延迟解组)与json非常相似。RawMessage适用于这样的示例。
yaml 包没有类似的 RawMessage
机制 - 但这种技术可以很容易地复制,如下所述:
type RawMessage struct {
unmarshal func(interface{}) error
}
func (msg *RawMessage) UnmarshalYAML(unmarshal func(interface{}) error) error {
msg.unmarshal = unmarshal
return nil
}
// call this method later - when we know what concrete type to use
func (msg *RawMessage) Unmarshal(v interace{}) error {
return msg.unmarshal(v)
}
因此,要在您的案例中利用这一点:
var fs struct {
Configs []struct {
Type string `yaml:"type"`
Config RawMessage `yaml:"config"` // delay unmarshaling
} `yaml:"fetchers"`
}
err = yaml.Unmarshal([]byte(data), &fs)
if err != nil {
return
}
根据配置“类型”(< code>aws或< code>kubernetes),您最终可以将< code>RawMessage解组为正确的具体类型:
aws := awsConfig{} // concrete type
err = c.Config.Unmarshal(&aws)
或:
k8s := kubernetesConfig{} // concrete type
err = c.Config.Unmarshal(&k8s)
这里的工作示例:https://go.dev/play/p/wsykOXNWk3H
通过实现解组器接口找到了解决方案:
type Fetcher struct {
Type string `yaml:"type"`
Config interface{} `yaml:"config"`
}
// Interface compliance
var _ yaml.Unmarshaler = &Fetcher{}
func (f *Fetcher) UnmarshalYAML(unmarshal func(interface{}) error) error {
var t struct {
Type string `yaml:"type"`
}
err := unmarshal(&t)
if err != nil {
return err
}
f.Type = t.Type
switch t.Type {
case "kubernetes":
var c struct {
Config kubernetesConfig `yaml:"config"`
}
err := unmarshal(&c)
if err != nil {
return err
}
f.Config = c.Config
case "aws":
var c struct {
Config awsConfig `yaml:"config"`
}
err := unmarshal(&c)
if err != nil {
return err
}
f.Config = c.Config
}
return nil
}
问题内容: 我正在尝试将YAML数据解析为字符串: 由于某种原因,config是一个空结构&{}。 问题答案: 您的结构的字段未导出。导出它们,它将起作用。
问题内容: 我正在尝试解组以下YAML(使用gopkg.in/yaml.v2): 使用以下代码: 但这给了我以下错误: 顶级属性是动态的,因此我需要将它们解析为字符串,结构中的所有其他键将始终相同,因此这些部分的结构也是如此。我该如何解析? (完整代码位于https://github.com/tirithen/unit- conversion/blob/master/convert.go#L84
本文向大家介绍yaml 基本的YAML类型,包括了yaml 基本的YAML类型的使用技巧和注意事项,需要的朋友参考一下 示例
主要内容:创建YAML文件的规则,YAML文件的基本组件,YAML基本要素简介经过前一节的学习,现在已经了解了YAML及其功能,下面通过语法和其他操作了解它的基础知识。 请记住,YAML包含人类可读的结构化格式。 创建YAML文件的规则 在YAML中创建文件时,应该记住以下基本规则 - YAML区分大小写。 这些文件使用作为扩展名。 YAML在创建YAML文件时不允许使用制表符,只允许使用空格。 YAML文件的基本组件 YAML的基本组成部分如下所述 - 常规块格式 此块格
我有一个GKE集群。 我使用从本地机器应用以下YAML: 申请了。很好。✅ 然后我用从集群中获取YAML,它返回了这个: 提前谢谢你。 我一直在想这件事。感谢您在这里提供的建议和建议。
问题内容: 我想将此yaml字符串转换为json,因为源数据是动态的,所以我无法将其映射到结构: 然后我想再次将该接口转换为json字符串: 但是发生错误: 问题答案: 前言: 我优化并改进了以下解决方案,并将其作为库发布在这里:。以下功能可作为。 问题在于,如果您使用最通用的类型来解组,则包用于解组键- 值对的默认类型将是。 第一个想法是使用: 但是,如果yaml配置的深度大于一,则此尝试将失败