Golang官方并没有提供Yaml解析包,所以需要使用第三方包。可用的第三方包有不少,这里选择的是

,这个包在github上有不少的star,也的确挺好用。其使用的是Apache License。

这个包提供的函数还是很少了,这真是一件好事(〃∀〃)

如果你不了解yaml,查看YAML简要入门


func Marshal(in interface{}) (out []byte, err error)

func Unmarshal(in []byte, out interface{}) (err error)

让我们来看一下这个例子:

package main

import (
"fmt"
"gopkg.in/yaml.v2"
) func main() {
var t T
s := `a: 1
x: 333
B: 2
F:
c: 3
开心: 10
愉悦: 30
S: 9
`
yaml.Unmarshal([]byte(s), &t) //输出为{0 1 0 0 0 0 30 333 0}
//a不会获得值,说明 结构字段名首字母大小控制是否接受值,首字母大写为接受
//b和B都没有获得值,未设置键时,默认解析时会将struct中字段的首字母转为小写,再去匹配Yaml,
//这样就没有能与yaml中B想匹配的了
//C 不能获得值说明,对应层次的字段才会赋值
//开心与D的例子,显示如何使用中文作为键
//X可以获得值说明,解析与声明的顺序无关
fmt.Println(t)
} type T struct {
a int
A int //yaml中a的值会给哪一个?
b int
B int //yaml中B的值会给B还是b,或者两者都不?
C int //能获得yaml中c的值吗?
开心 int //能获得yaml开心的值吗?
D int `yaml:"愉悦"` //使用struct标签,为D int设置键为“愉悦”
//`yaml:"key[, tag]"`
X int //X能获得值吗
s int `yaml:"S"`
}

你可以拷贝运行一下这段代码,自己感受下。

如果如何struct中还有struct呢?

package main

import (
"fmt"
"log" "gopkg.in/yaml.v2"
) type StructA struct {
A string `yaml:"a"`
} type StructB struct {
StructA
C StructA
B string `yaml:"b"`
} var data = `
a: a string from struct A
b: a string from struct B
c:
a: a string from c.a
` func main() {
var b StructB err := yaml.Unmarshal([]byte(data), &b)
if err != nil {
log.Fatalf("cannot unmarshal data: %v", err)
}
fmt.Println(b.B)
fmt.Println(b.A)
fmt.Println(b.C.A)
/*
输出为:
a string from struct B //可以看到匿名struct没有获得值 a string from c.a
*/
}
inline
type StructB struct {
StructA`yaml:",inline"`
C StructA
B string `yaml:"b"`
}

func UnmarshalStrict(in []byte, out interface{}) (err error)

UnmarshalStrict和Unmarshal基本上一样,但是多了一点限制。

Yaml中的字段必须要有给定的接收对象,而在Unmarshal中它们会被忽略。


type Decoder
func NewDecoder(r io.Reader) *Decoder
func (dec *Decoder) Decode(v interface{}) (err error)
package main

import (
"fmt"
"os" "gopkg.in/yaml.v2"
) type StructA struct {
A string `yaml:"a"`
} type StructB struct {
StructA
C StructA
B string `yaml:"b"`
} func main() {
var b StructB yfile, _ := os.Open("test.yaml") //test.yaml由下一个例子生成
defer yfile.Close() ydecode:= yaml.NewDecoder(yfile)
ydecode.Decode(&b) //注意这里为指针
fmt.Println(b)
}

type Encoder
func NewEncoder(w io.Writer) *Encoderfunc (e *Encoder) Close() (err error)
func (e *Encoder) Encode(v interface{}) (err error)---
package main

import (
"log"
"os" "gopkg.in/yaml.v2"
) type StructA struct {
A string `yaml:"a"`
} type StructB struct {
StructA
C StructA
B string `yaml:"b"`
} var data = `
a: a string from struct A
b: a string from struct B
c:
a: a string from c.a
` func main() {
var b StructB
x := 22 err := yaml.Unmarshal([]byte(data), &b)
if err != nil {
log.Fatalf("cannot unmarshal data: %v", err)
} yfile, _ := os.Create("test.yaml")
defer yfile.Close() yencoder := yaml.NewEncoder(yfile)
defer yencoder.Close()
yencoder.Encode(b)
yencoder.Encode(b)
yencoder.Encode(x)
yencoder.Encode(44)
}

这篇文章根据官方文档写成,我可能没有表述的很清楚,请查阅官方文档