go-ini入门教程

go-ini简介

Package ini provides INI file read and write functionality in Go.

在实际开发时,配置信息一般不会在代码里硬编码,通常是放在配置文件里,或者数据库、缓存里。今天介绍的 go-ini 就是一个读写 ini文件的库。

配置文件格式有很多,常用的有 jsonxmlini。其中 ini 是以节(section)和键(key)构成,如下所示:

#debug or release
RUN_MODE = debug [app]
PAGE_SIZE = 10

快速使用

1、下载安装

使用一个特定版本:

$ go get gopkg.in/ini.v1

使用最新版本:

$ go get github.com/go-ini/ini

如需更新请添加 -u 选项。

2、创建两个文件(my.inimain.go),这里选择放在 /home/ini-sample 目录。

$ mkdir -p /home/ini-sample
$ cd /home/ini-sample
$ touch my.ini main.go
$ tree .
.
├── main.go
└── my.ini 0 directories, 2 files

3、编译 my.ini 文件并输入以下内容:

#debug or release
RUN_MODE = debug [app]
PAGE_SIZE = 10 [server]
HTTP_PORT = 8000
READ_TIMEOUT = 60
WRITE_TIMEOUT = 60 [database]
TYPE = mysql
USER = 数据库账号
PASSWORD = 数据库密码
#127.0.0.1:3306
HOST = 数据库IP:数据库端口号
NAME = blog
TABLE_PREFIX = blog_

4、接着编写 main.go 文件来操作刚才创建的配置文件。

package main
import (
"fmt"
"os"
"gopkg.in/ini.v1"
)
func main() {
cfg, err := ini.Load("my.ini")
if err != nil {
fmt.Printf("Fail to read file: %v", err)
os.Exit(1)
}
// 典型读取操作,默认分区可以使用空字符串表示
fmt.Println("Run Mode:", cfg.Section("").Key("RUN_MODE").String())
fmt.Println("Page Size:", cfg.Section("app").Key("PAGE_SIZE").String())
// 试一试自动类型转换
fmt.Printf("Http Port: (%[1]T) %[1]d\n", cfg.Section("server").Key("HTTP_PORT").MustInt(9999))
// 差不多了,修改某个值然后进行保存
cfg.Section("").Key("RUN_MODE").SetValue("release")
cfg.SaveTo("my.ini.local")
}

5、运行程序,可以看到以下输出:

$ go run main.go
Run Mode: debug
Page Size: 10
Http Port: (int) 8000 $ cat my.ini.local
# debug or release
RUN_MODE = release [app]
PAGE_SIZE = 10 [server]
HTTP_PORT = 8000
READ_TIMEOUT = 60
WRITE_TIMEOUT = 60 [database]
TYPE = mysql
USER = 数据库账号
PASSWORD = 数据库密码
# 127.0.0.1:3306
HOST = 数据库IP:数据库端口号
NAME = blog
TABLE_PREFIX = blog_

操作分区(Section)

获取指定分区:

sec, err := cfg.GetSection("section name")

如果想要获取默认分区,则可以用空字符串代替分区名:

sec, err := cfg.GetSection("")

操作键值(Value)

获取一个类型为字符串(string)的值:

val := cfg.Section("").Key("key name").String()

Must*方法

当我们知道配置的键值是哪种格式时,可以使用 Must* 方法来获取。

v = cfg.Section("").Key("BOOL").MustBool()
v = cfg.Section("").Key("FLOAT64").MustFloat64()
v = cfg.Section("").Key("INT").MustInt()
v = cfg.Section("").Key("INT64").MustInt64()
v = cfg.Section("").Key("UINT").MustUint()
v = cfg.Section("").Key("UINT64").MustUint64()
v = cfg.Section("").Key("TIME").MustTimeFormat(time.RFC3339)
v = cfg.Section("").Key("TIME").MustTime() // RFC3339
// 由 Must 开头的方法名允许接收一个相同类型的参数来作为默认值,
// 当键不存在或者转换失败时,则会直接返回该默认值。
// 但是,MustString 方法必须传递一个默认值。
v = cfg.Section("").Key("String").MustString("default")
v = cfg.Section("").Key("BOOL").MustBool(true)
v = cfg.Section("").Key("FLOAT64").MustFloat64(1.25)
v = cfg.Section("").Key("INT").MustInt(10)
v = cfg.Section("").Key("INT64").MustInt64(99)
v = cfg.Section("").Key("UINT").MustUint(3)
v = cfg.Section("").Key("UINT64").MustUint64(6)
v = cfg.Section("").Key("TIME").MustTimeFormat(time.RFC3339, time.Now())
v = cfg.Section("").Key("TIME").MustTime(time.Now()) // RFC3339

In*方法

获取键值时设定候选值,可以使用 In* 方法:

v = cfg.Section("").Key("STRING").In("default", []string{"str", "arr", "types"})
v = cfg.Section("").Key("FLOAT64").InFloat64(1.1, []float64{1.25, 2.5, 3.75})
v = cfg.Section("").Key("INT").InInt(5, []int{10, 20, 30})
v = cfg.Section("").Key("INT64").InInt64(10, []int64{10, 20, 30})
v = cfg.Section("").Key("UINT").InUint(4, []int{3, 6, 9})
v = cfg.Section("").Key("UINT64").InUint64(8, []int64{3, 6, 9})
v = cfg.Section("").Key("TIME").InTimeFormat(time.RFC3339, time.Now(), []time.Time{time1, time2, time3})
v = cfg.Section("").Key("TIME").InTime(time.Now(), []time.Time{time1, time2, time3}) // RFC3339

如果获取到的值不是候选值的任意一个,则会返回默认值,而默认值不需要是候选值中的一员。

结构体与分区映射

有时候我们不想逐个获取值,而是把分区内的值放到一个结构体里,以便使用。

配置文件:

#debug or release
RUN_MODE = debug [app]
PAGE_SIZE = 10 [server]
HTTP_PORT = 8000
READ_TIMEOUT = 60
WRITE_TIMEOUT = 60 [database]
TYPE = mysql
USER = 数据库账号
PASSWORD = 数据库密码
#127.0.0.1:3306
HOST = 数据库IP:数据库端口号
NAME = blog
TABLE_PREFIX = blog_

代码:

type Database struct {
Type string
User string
Password string
Host string
Name string
TablePrefix string
} func Setup() {
Cfg, err := ini.Load("conf/app.ini")
if err != nil {
log.Fatalf("Fail to parse 'conf/app.ini': %v", err)
} err = Cfg.Section("database").MapTo(DatabaseSetting)
if err != nil {
log.Fatalf("Cfg.MapTo DatabaseSetting err: %v", err)
}
}

使用心得

通常配置文件很少变更的,一般使用单例,在 go 里就是包内变量了,由于只需要读取一次,所以一般会在 init 方法里读取。

另外关于配置热更新,可以查看这份文章:热更新配置文件

参考资料

go-ini入门教程的更多相关文章

  1. 21分钟 MySQL 入门教程(转载!!!)

    21分钟 MySQL 入门教程 目录 一.MySQL的相关概念介绍 二.Windows下MySQL的配置 配置步骤 MySQL服务的启动.停止与卸载 三.MySQL脚本的基本组成 四.MySQL中的数 ...

  2. [视频]K8软件破解脱壳入门教程

    [视频]K8软件破解脱壳入门教程 链接:https://pan.baidu.com/s/1aV9485MmtRedU6pzyr--Vw 提取码:vbak C:\Users\K8team\Desktop ...

  3. 观看杨老师(杨旭)Asp.Net Core MVC入门教程记录

    观看杨老师(杨旭)Asp.Net Core MVC入门教程记录 ASP.NET Core MVC入门 Asp.Net Core启动和配置 Program类,Main方法 Startup类 依赖注入,I ...

  4. MySQL 快速入门教程

    转:MySQL快速 入门教程 目录 一.MySQL的相关概念介绍 二.Windows下MySQL的配置 配置步骤 MySQL服务的启动.停止与卸载 三.MySQL脚本的基本组成 四.MySQL中的数据 ...

  5. Mysql学习总结(12)——21分钟Mysql入门教程

    21分钟 MySQL 入门教程 目录 一.MySQL的相关概念介绍 二.Windows下MySQL的配置 配置步骤 MySQL服务的启动.停止与卸载 三.MySQL脚本的基本组成 四.MySQL中的数 ...

  6. Veins(车载通信仿真框架)入门教程(二)——调用第三方库

    Veins(车载通信仿真框架)入门教程(二)——调用第三方库 在借助Veins进行自己的研究时我们经常需要实现一些比较复杂的功能,有时就需要借助第三方库的帮助. 博主的研究需要使用神经网络,但是自己编 ...

  7. Veins(车载通信仿真框架)入门教程

    Veins入门教程——教你如何下手研究 目录 Veins入门教程——教你如何下手研究 目录 废话少说! 讲解omnetpp.ini!(挑关键的) 讲解RSUExampleScnario.ned! 注意 ...

  8. BussinessSkinForm 入门教程

    BussinessSkinForm 入门教程 By 刘家君(qufo) 作者:刘家君 工作单位:福建省 泉州鹭燕医药有限公司 职务:网络管理员 网名:qufo Mail:qufo@tom.com,qu ...

  9. wepack+sass+vue 入门教程(三)

    十一.安装sass文件转换为css需要的相关依赖包 npm install --save-dev sass-loader style-loader css-loader loader的作用是辅助web ...

随机推荐

  1. Battery API All In One

    Battery API All In One https://caniuse.com/?search=Battery navigator.getBattery() /* Promise {<pe ...

  2. event duplication bind bug & h5 dataset flag solution

    event duplication bind bug & h5 dataset flag solution https://codepen.io/xgqfrms/full/PaRBEy/ OK ...

  3. node mailer & email bot

    node mailer & email bot email https://nodemailer.com/about/ https://github.com/nodemailer/nodema ...

  4. image to cur (cursor icons)

    image to cur (cursor icons) mouse-cursor-pointer https://onlineconvertfree.com/convert-format/jpg-to ...

  5. .Net Core 3.1浏览器后端服务(三) Swagger引入与应用

    一.前言 前后端分离的软件开发方式已逐步成为互联网项目开发的业界标准,前后端分离带来了诸多好处的同时,也带来了一些弊端. 接口文档的维护就是其中之一,起初前后端约定文档规范,开发的很愉快,随着时间推移 ...

  6. 防抖和节流及对应的React Hooks封装

    Debounce debounce 原意消除抖动,对于事件触发频繁的场景,只有最后由程序控制的事件是有效的. 防抖函数,我们需要做的是在一件事触发的时候设置一个定时器使事件延迟发生,在定时器期间事件再 ...

  7. 微信小程序引入ECharts组件

    首先打开ECharts网页 https://echarts.apache.org/zh/tutorial.html#%E5%9C%A8%E5%BE%AE%E4%BF%A1%E5%B0%8F%E7%A8 ...

  8. WPF -- 一种圆形识别方案

    本文介绍一种圆形的识别方案. 识别流程 判断是否为封闭图形: 根据圆的方程,取输入点集中的1/6.3/6.5/6处的三个点,求得圆的方程,获取圆心及半径: 取点集中的部分点,计算点到圆心的距离与半径的 ...

  9. django 内置“信号”机制和自定义方法

    一.引子 在操作数据的时候,假设我们需要记录一些日志,这个时候,我们需要用什么来显示这个需求呢?装饰器?装饰器只能先实现整体的操作.在django 里面有这么一个东西--信号 下面我们就来了解了解它. ...

  10. Linux 安装python 模块及库

    转载于https://blog.csdn.net/csdn_am/article/details/79924744 有时我们使用下载python 自带的pip 安装一些工具包时,会报如下错误 找不到满 ...