我正在尝试在封送结构以配置YAML时使用YAML v3。
注:更新:我最初的例子有点过于简化了。我的实际要求如下:
例如,我有:
package main
import (
"fmt"
"io/ioutil"
"gopkg.in/yaml.v3"
)
type Ec2 struct {
Class string `yaml:"class"`
Ip string `yaml:"ip"`
}
type Vpc struct {
Subnet string `yaml:"subnet"`
Igw interface{} `yaml:"igw"`
}
type Config struct {
Ec2 Ec2 `yaml:"ec2"`
Vpc Vpc `yaml:"vpc"`
}
func main() {
c := Config{}
bytes, err := yaml.Marshal(c)
if err != nil {
fmt.Println(err)
}
ioutil.WriteFile("config.yaml", bytes, 0644)
}
在pwd
中创建一个名为config.yaml
的文件,如:
ec2:
class: ""
ip: ""
vpc:
subnet: ""
igw: null
但我正在尝试生成配置文件(在本例中为config.yaml(,如:
ec2:
# This section is for EC2
class: ""
ip: ""
vpc:
# This section is for VPC
subnet: ""
igw: null
使用V.3
可以实现这一点吗?
有两种方法可以利用yaml.v3
及其注释功能:
- 手工构建
yaml.Node
树(繁琐的维护;精确的值更新( - 将模板解析为
yaml.Node
树(易于维护;难以更新值(
方法1:
手工制作YAML节点树:
config = &yaml.Node{
Kind: yaml.DocumentNode,
Content: []*yaml.Node{
&yaml.Node{
Kind: yaml.MappingNode,
Content: []*yaml.Node{
&yaml.Node{
Kind: yaml.ScalarNode,
Value: "ec2",
HeadComment: "# This section is for EC2",
},
&yaml.Node{
Kind: yaml.ScalarNode,
Style: yaml.DoubleQuotedStyle,
Value: "", // <- field value goes here
},
&yaml.Node{
Kind: yaml.ScalarNode,
Value: "vpc",
HeadComment: "# This section is for VPC",
},
&yaml.Node{
Kind: yaml.ScalarNode,
Style: yaml.DoubleQuotedStyle,
Value: "", // <- field value goes here
},
},
},
},
}
工作游乐场示例:https://play.golang.org/p/Z6iw29rHZXk
输出:
# This section is for EC2
ec2: ""
# This section is for VPC
vpc: ""
方法2:
阅读YAML模式的模板,例如
var yamlSchema = []byte(`
# EC2 header-comment
ec2: ""
# This section is for VPC
vpc: ""
`)
然后在运行时将其解析为yaml.Node
树,如下所示:
var c yaml.Node
err := yaml.Unmarshal(yamlSchema, &c)
但是,作为一个yaml.Node
树——它嵌套了yaml.Node
的片段——你需要以编程的方式找到你的字段值,所以当你为写作封送配置时,这些值会与正确的字段配对。
例如,这个今天可能有效:
c.Content[0].Content[1].Value = ec2Value // dangerous
但不是明天,当模式改变时。
遍历映射并查找字段值ec2
,然后将其值放置在相邻节点中是正确的方法。
Playground示例显示了如何将页眉/页脚/内联注释添加到架构中,例如
# This section is for EC2
ec2: "" # <-- place user input here
# footer EC2
# This section is for VPC
vpc: ""