• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

golang:flag.String、flag.Parse

武飞扬头像
java_xxxx
帮助1

前言

项目中经常会有这样的需求,一个项目部署在不同的服务器上,而不同的服务器上的配置是不同的,例如一个项目,即部署在国内,又部署在美东,但是国内是国内的一套数据库、redis等等,而国外又是连接国外的数据库、redis等等,这样就需要我们根据部署的环境去加载响应的配置。
那么在go程序启动main运行的时候,我们往往就要加载响应的配置。

具体事件及解决方案

一般部署都是在项目中的.sh脚本文件里,我们在脚本文件里去得到当前的服务器是在国内还是国外,然后依此将服务器发信息传递到go里。
例如,项目中有一个start.sh文件,我们项目根目录有一个conf文件夹
结构如下:

conf/test1/log.conf
conf/test1/mysql.conf
conf/test1/redis.conf

conf/test2/log.conf
conf/test2/mysql.conf
conf/test2/redis.conf

在sh文件里我们判断了当前服务器为test2,在sh文件里

  // 即为将config_conf变量的值传递给go代码
  // 注意,这里的 -后面的d,即为flag.String里的第一个参数,第一个参数写的啥,这里的-后面就是啥
  exec "./bin/$app" -d "$config_conf"
  // 此时config_conf值为conf/test2

下面我们来看go代码

var (
	defaultPath = flag.String("d", "./conf/test1/", "conf path")
	LogFile     = *defaultPath   "log.json"
	confFile    = *defaultPath   "redis.toml"
	Cfg         Config
)

// InitConf 初始化配置文件
func InitConf() error {
	flag.Parse()
	// 如果下面不重新赋值,那么logfile与confile的值仍旧为旧值,即
	// ./conf/test1/...
	LogFile     = *defaultPath   "log.json"
	confFile    = *defaultPath   "project.toml"
	fmt.Println(LogFile)//conf/test2/log.conf
	fmt.Println(confFile)//conf/test2/redis.conf
学新通

至此,go代码中就读取到配置文件的信息了。

再来看下flag.Parse()的源码及注释,啥意思呢,就是在变量定义之后,程序访问标志之前去调用该函数,注意flag.String("d"第一个参数,写的是谁,那么.sh文件里的 exec "./bin/ a p p " − d " app" -d " app"d"config_conf"的-d就是谁,例如flag.String第一个参数为-c那么exec "./bin/ a p p " − c " app" -c" app"c"config_conf"里就是-c

// Parse parses the command-line flags from os.Args[1:]. Must be called
// after all flags are defined and before flags are accessed by the program.
func Parse() {
	// Ignore errors; CommandLine is set for ExitOnError.
	CommandLine.Parse(os.Args[1:])
}

上面的注释啥意思呢,就是在变量定义之后,程序访问标志之前去调用该函数。
即下面代码中LogFile、confFile都已在var定义过了,然后还并没有使用defaultPath标志变量,然后flag.Parse()函数会将运行命令中的参数通过d这个标志赋值给defaultPath,然后flag.Parse()之后的代码再去取defaultPath的值的时候就拿到了运行命令传递过来的值,即/conf/test2/

var (
	defaultPath = flag.String("d", "./conf/test1/", "conf path")
	LogFile     = "log.json"
	confFile    = "redis.toml"
	Cfg         Config
)

// InitConf 初始化配置文件
func InitConf() error {
	flag.Parse()
	// 如果下面不重新赋值,那么logfile与confile的值仍旧为旧值,即
	// ./conf/test1/...
	LogFile     = *defaultPath   "log.json"
	confFile    = *defaultPath   "project.toml"
	fmt.Println(LogFile)//conf/test2/log.conf
	fmt.Println(confFile)//conf/test2/redis.conf
学新通

如果下面这样写是不对的,下面的代码在 flag.Parse()之后并没有去将defaultPath的新值赋值给LogFile、confFile所以运行时取到的还是defaultPath定义的旧值,即./conf/test1/

var (
	defaultPath = flag.String("d", "./conf/test1/", "conf path")
	LogFile     = *defaultPath   "log.json"
	confFile    = *defaultPath   "redis.toml"
	Cfg         Config
)

// InitConf 初始化配置文件
func InitConf() error {
	flag.Parse()

代码测试

其实无论是c语言还是golang语言或是其他语言,启动应用程序时都可以带一些参数,然后系统根据传入的参数进行特点的工作。如:./main -b /home/backupdir -d true

package main

import (
    "flag"
    "fmt"
)

func main() {
    backup_dir := flag.String("b", "/home/default_dir", "backup path")
    debug_mode := flag.Bool("d", false, "debug mode")

    flag.Parse()

    fmt.Println("backup_dir: ", *backup_dir)
    fmt.Println("debug_mode: ", *debug_mode)
}

/**
    启动命令:go run main.go -b /home/backup
    输出结果:
        backup_dir:  /home/backup  // 因为指定了路径,所以覆盖了默认路径
        debug_mode:  false         // 启动命令里不带 -d 参数,所以启用默认值
 */
学新通

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgfaacb
系列文章
更多 icon
同类精品
更多 icon
继续加载