yaml文件是现在很流行的一种配置文件,具有结构清晰,层次分明的特点。它是json的一个超集,解析出来的内容在python中对应着字典,go语言中可以解析为结构体。
曾经作为初学者,现在依旧是初学者的我,用go解析yaml文件,也是一个文件定义一次结构体,结构体中定义大量的tag是非常繁琐的工作。于是我就自己写了一个代码,解析为一个通用的map,并序列化为json,为什么序列化为json呢,方便以后web交换数据,或者跨语言的使用。
直接上代码:
package config
/*the interface load config yaml file,return json and error*/
type Config interface {
LoadConfigl(file string) (jsonByte []byte, err error)
}
/*
the default config
you can implement config
if you do not implement,will use default config
that will be used for Configuration Center in the future
*/
type defaultConfig map[string]interface{}
通过定义一个Config接口签名Loadconfig方法。
定义一个defaultconfig 的type 用于解析yaml
package config
import (
"encoding/json"
"fmt"
"io"
"os"
"strings"
yaml "gopkg.in/yaml.v3"
)
/*
load yaml config
return json data and error
*/
func (dc *defaultConfig)loadyaml(file string)(jsonByte []byte,err error){
confile,ok := os.Open(file)
err = ok
if err != nil {
return
}
defer confile.Close()
configmaps := []defaultConfig{}
dec := yaml.NewDecoder(confile)
for err == nil {//decode yaml file if err != nil
cf := defaultConfig{}
err = dec.Decode(cf)
if err != nil && err != io.EOF {
return
}
if len(cf) != 0 { // if cf has key value append it
configmaps =append(configmaps, cf)
}
}
if len(configmaps) == 1 {
(*dc)["configs"] = configmaps[0] // pasre one file
}else{
(*dc)["configs"] = configmaps //pasre more than one file
}
return dc.parseJosn()
}
func (dc *defaultConfig)LoadConfig(file string)(jsonByte []byte,err error){
return dc.loadyaml(file)
}
/*pasre dc to json*/
func (dc *defaultConfig)parseJosn()([]byte,error){
return json.Marshal(dc)
}
defaultConfig 通过实现Config的方法,实现了该接口。接着再来一个外部的方法,通过config,来实现解析yaml:
package config
import (
"errors"
"io/ioutil"
"strings"
)
var(
errfilesyntax error = errors.New("syntax erorr")
errstyle error = errors.New("this is a unkonw type of the config file")
erremptyinterface error = errors.New("the interface config is nil")
erremptyfile error = errors.New("the config file is nil")
)
func Mashal(c Config,file string)(jsonstr []byte,err error){
return mashal(c,file)
}
func mashal(c Config,file string)(jsonstr []byte,err error){
if c == nil {
err = erremptyinterface
return
}
if file == "" {
err = erremptyfile
return
}
if strings.HasSuffix(file,".yaml") || strings.HasSuffix(file,".yml") {
if jsonstr,err = c.LoadConfig(file);len(jsonstr)==0 && err == nil{ //如果自己实现的Config接口没有具体的实现,就会使用默认的config接口。这个主要是方便大家定制。
dcs := &defaultConfig{}
c = dcs
return c.LoadConfig(file)
}
return
}
err = errstyle
return
}
func NewConfig()(Config){ //提供一个创建Config接口的方法。
return &defaultConfig{}
}
到此能够让你解析所有yaml的go程序大体完成。你可以用通过gjosn去使用这个配置的json,也可以反序列化成你想要的结构体,map来使用这些yaml文件。