一、通过文件管理配置
在项目中通常使用不同格式的文件来管理配置,比如将一些数据放在配置文件中以降低代码耦合和提高代码的可维护性,亦或者通过配置文件来设置各种应用程序的启动参数以及针对不同的环境使用不同的配置文件等。
二、使用 YAML 文件作为配置文件
YAML 既 “YAML Ain’t a Markup Language”
- YAML 可以表达列表、散列表,标量等数据。它使用空白符号缩进和大量依赖外观的特色,特别适合用来表达或编辑数据结构、各种配置文件等。
- YAML 配置文件后缀为
.yml
YAML 基本语法规则如下:
- 大小写敏感
- 使用缩进表示层级关系
- 缩进不允许使用 tab,只允许空格
- 缩进的空格数不重要,只要相同层级的元素左对齐即可
#
表示注释,从它开始到行尾都被忽略- 锚点
&
:标注一个内容,锚点名称自定义 - 在 yaml 里,用 on、1、true 来表示true,off、0、false 来表示 false
- yaml 中,空值可以用 null 或 ~ 表示
name: "stark" age: 33 address: - NYC - BOS - WDC student: name: "peter" age: 18 复制代码
YAML 的读取会使用到第三方的 yaml 库,因此需要通过 go get
命令来进行安装。
go get github.com/go-yaml/yaml 复制代码
我们以一个简单的 HTTP Server 为例,首先创建两个配置文件 prod_config.yml 和 test_config.yml,分别表示生产环境和测试环境。
# test_config.yml tag: "test" port: "8000" 复制代码
# prod_config.yml tag: "prod" port: "9000" 复制代码
接着定义一个 Config 结构体,用来封装配置数据
type Config struct { Tag string `json:"tag"` Port string `json:"port"` } 复制代码
然后再定义一个函数 GetConfigDataFromYAML,用来读取指定配置文件,将配置文件中的数据封装到一个实例化的结构体上。
func GetConfigDataFromYAML(file string) Config { // 读取 YAML 配置文件 f, err := ioutil.ReadFile(file) if err != nil { log.Fatal(err) } c := Config{} err = yaml.Unmarshal(f, &c) if err != nil { log.Fatal(err) } return c } 复制代码
最后在 main 函数中创建一个简单的 HTTP 服务
//noinspection ALL import ( "github.com/go-yaml/yaml" "io/ioutil" "log" "net/http" ) //noinspection ALL func main(){ // 在测试环境中启动服务 config := GetConfigDataFromYAML("14-io/test_config.yml") http.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) { writer.Write([]byte(config.Tag)) }) http.ListenAndServe(":" + config.Port, nil) } 复制代码
运行 main 文件,浏览器打开 http://localhost:8000/
如果想要在生产环境启动,那么只需要把配置文件改成 prod_config.yaml 即可。
三、使用 JSON 文件作为配置文件
JSON 文件可以和 Go 的结构体进行相互转换,JSON 是一种声明键值的简单方式,同时 JSON 格式也是标准的配置文件方式。
Go 程序可以读取存储在 JSON 文件中各项配置数据,然后反序列化为结构体,将各种配置数据封装到实例化的结构体当中,通过获取结构体的属性来获取配置数据。
使用 JSON 格式文件作为配置文件,首先创建两个配置文件 prod_config.json 和 test_config.json,分别表示生产环境和测试环境。
{ "tag": "test", "port": "8000" } 复制代码
{ "tag": "prod", "port": "9000" } 复制代码
然后再定义一个函数 GetConfigDataFromJSON,用来读取指定配置文件,将配置文件中的数据封装到一个实例化的结构体上。
func GetConfigDataFromJSON(file string) Config { // 读取 JSON 配置文件 f, err := ioutil.ReadFile(file) if err != nil { log.Fatal(err) } c := Config{} err = json.Unmarshal(f, &c) if err != nil { log.Fatal(err) } return c } 复制代码
最后在 main 函数中创建一个简单的 HTTP 服务
func main(){ // 在测试环境中启动服务 config := GetConfigDataFromJSON("14-io/test_config.json") http.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) { writer.Write([]byte(config.Tag)) }) fmt.Println(config.Port) http.ListenAndServe(":" + config.Port, nil) } 复制代码
运行 main 文件,浏览器打开 http://localhost:8000/
如果想要在生产环境启动,那么只需要把配置文件改成 prod_config.json 即可。
四、使用 TMOL 文件作为配置文件
TOML 既(Tom's Obvious, Minimal Language)是一种专门为存储配置文件而设置的格式,与 JSON 相比表达能力更强,更容易映射 Go 类型。
JSON 是专门为序列化设计的,而 TOML 则是专门为存储配置文件而设计的。TOML 可以使用 #
注释,且后缀名为 .toml
,它的基本语法如下:
# filename: test_config.toml tag = "test" port = "8000" 复制代码
TOML 不是 Go 的组成部分,在标准库中没有相关的包,可以自己编写代码或者通过第三方的 toml 包来读取,使用 toml 包需要单独进行安装。
go get github.com/BurntSushi/toml 复制代码
toml 标注库中的 DecodeFile
的函数可以直接将配置文件中的数据封装到一个结构体中,而不用像 YAML 和 JSON 要先通过 ioutil
的 ReadFile
函数读取文件,再转化成结构体。
import ( "fmt" "github.com/BurntSushi/toml" "log" ) //noinspection ALL func main(){ config := Config{} _, err := toml.DecodeFile("14-io/test_config.toml", &config) if err != nil { log.Fatal(err) } fmt.Printf("%+v\n", config) # {Tag:test Port:8000} fmt.Printf("%T", config) # main.Config } type Config struct { Tag string `json:"tag"` Port string `json:"port"` }