如何解组 yaml 数组?
How to unmarshal a yaml array?
我有下一个 yaml,如果我在 online yaml website 中验证它,它说它是有效的:
- {"foo": "1", "bar": "2"}
然后,我写了一段代码来解析这个 yaml 中的值 1
和 2
,如下所示:
test.go:
package main
import "gopkg.in/yaml.v2"
import "fmt"
type Config struct {
Foo string
Bar string
}
type Configs struct {
Cfgs []Config `foobar`
}
func main() {
//var data = `
// foobar:
// - foo: 1
// bar: 2
//`
var data = `
- foo: 1
bar: 2
`
source := []byte("foobar:" + data)
var configs Configs
err := yaml.Unmarshal(source, &configs)
if err != nil {
fmt.Println("error: %v", err)
}
fmt.Printf("--- configs:\n%v\n\n", configs)
fmt.Println(configs.Cfgs[0].Foo)
fmt.Println(configs.Cfgs[0].Bar)
}
它工作正常如下:
shubuntu1@shubuntu1:~/20210810$ go run test.go
--- configs:
{[{1 2}]}
1
2
有什么问题?
你可以看到我在这里做了一个解决方法,在原始 yaml 之前添加特殊的 foobar
键,然后我可以使用 type Configs struct
解组它:
来自
- foo: 1
bar: 2
至
foobar:
- foo: 1
bar: 2
所以,如果我不使用解决方法添加前缀foobar:
,我怎么能直接解析- {"foo": 1, "bar": 2}
?
由于您的 YAML
数据是一个数组,将其解组为 Config
结构的数组。
package main
import (
"fmt"
"gopkg.in/yaml.v2"
)
type Config struct {
Foo string
Bar string
}
func main() {
var configs []Config
var data = `
- foo: 1
bar: 2
`
err := yaml.Unmarshal([]byte(data), &configs)
if err != nil {
panic(err)
}
fmt.Println(configs)
}
输出:
[{1 2}]
试穿 - Go Playground
既然问题已经回答了,我想我可以补充一些东西来讨论:
var data = `
- foo: 1
bar: 2
`
此处的数据变量,按照您的写法,将包含每行开头的缩进。
此处的额外缩进将与所有实际的 yaml 数据一起传递到 yaml.Unmarshal()
,这可能会造成混乱,因为 gofmt
格式化您的代码以使用 TAB 作为缩进 和 TAB 缩进在 yaml 中被禁止 ().
如果在 yaml 中使用制表符作为缩进,在尝试解组时会抛出这样的错误:
yaml: line 1: found a tab character that violates indentation
您最好从单独的文件中加载 data
以避免此类问题。
package main
import (
"fmt"
"io/ioutil"
"gopkg.in/yaml.v2"
)
type Config struct {
Foo string
Bar string
}
func main() {
var configs []Config
source, err := ioutil.ReadFile("config.yaml")
if err != nil {
fmt.Printf("failed reading config file: %v\n", err)
}
err = yaml.Unmarshal(source, &configs)
if err != nil {
fmt.Printf("error: %v\n", err)
}
fmt.Printf("config:\n%+v\n", configs)
}
config.yaml:
- foo: 1
bar: 2
输出:
config:
[{Foo:1 Bar:2}]
我有下一个 yaml,如果我在 online yaml website 中验证它,它说它是有效的:
- {"foo": "1", "bar": "2"}
然后,我写了一段代码来解析这个 yaml 中的值 1
和 2
,如下所示:
test.go:
package main
import "gopkg.in/yaml.v2"
import "fmt"
type Config struct {
Foo string
Bar string
}
type Configs struct {
Cfgs []Config `foobar`
}
func main() {
//var data = `
// foobar:
// - foo: 1
// bar: 2
//`
var data = `
- foo: 1
bar: 2
`
source := []byte("foobar:" + data)
var configs Configs
err := yaml.Unmarshal(source, &configs)
if err != nil {
fmt.Println("error: %v", err)
}
fmt.Printf("--- configs:\n%v\n\n", configs)
fmt.Println(configs.Cfgs[0].Foo)
fmt.Println(configs.Cfgs[0].Bar)
}
它工作正常如下:
shubuntu1@shubuntu1:~/20210810$ go run test.go
--- configs:
{[{1 2}]}
1
2
有什么问题?
你可以看到我在这里做了一个解决方法,在原始 yaml 之前添加特殊的 foobar
键,然后我可以使用 type Configs struct
解组它:
来自
- foo: 1
bar: 2
至
foobar:
- foo: 1
bar: 2
所以,如果我不使用解决方法添加前缀foobar:
,我怎么能直接解析- {"foo": 1, "bar": 2}
?
由于您的 YAML
数据是一个数组,将其解组为 Config
结构的数组。
package main
import (
"fmt"
"gopkg.in/yaml.v2"
)
type Config struct {
Foo string
Bar string
}
func main() {
var configs []Config
var data = `
- foo: 1
bar: 2
`
err := yaml.Unmarshal([]byte(data), &configs)
if err != nil {
panic(err)
}
fmt.Println(configs)
}
输出:
[{1 2}]
试穿 - Go Playground
既然问题已经回答了,我想我可以补充一些东西来讨论:
var data = `
- foo: 1
bar: 2
`
此处的数据变量,按照您的写法,将包含每行开头的缩进。
此处的额外缩进将与所有实际的 yaml 数据一起传递到 yaml.Unmarshal()
,这可能会造成混乱,因为 gofmt
格式化您的代码以使用 TAB 作为缩进 和 TAB 缩进在 yaml 中被禁止 ().
如果在 yaml 中使用制表符作为缩进,在尝试解组时会抛出这样的错误:
yaml: line 1: found a tab character that violates indentation
您最好从单独的文件中加载 data
以避免此类问题。
package main
import (
"fmt"
"io/ioutil"
"gopkg.in/yaml.v2"
)
type Config struct {
Foo string
Bar string
}
func main() {
var configs []Config
source, err := ioutil.ReadFile("config.yaml")
if err != nil {
fmt.Printf("failed reading config file: %v\n", err)
}
err = yaml.Unmarshal(source, &configs)
if err != nil {
fmt.Printf("error: %v\n", err)
}
fmt.Printf("config:\n%+v\n", configs)
}
config.yaml:
- foo: 1
bar: 2
输出:
config:
[{Foo:1 Bar:2}]