<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          讓flag支持從文件中讀取命令行參數(shù)

          共 3187字,需瀏覽 7分鐘

           ·

          2021-11-30 23:43

          golang標準庫提供了flag包來處理命令行參數(shù)。常規(guī)的使用都是在命令行中啟動服務的時候一一的輸入,讓程序解析。今天給大家介紹一種可以從文件中讀取命令行參數(shù)的實現(xiàn)方法。


          ? 01 flag的常規(guī)應用
          下面我們通過代碼來演示下flag的常規(guī)應用。如下代碼:
          var (  RedisAddress string)
          func init() { flag.StrVar(&RedisAddress, "redis_address", "127.0.0.1", "this is redis address")}
          func main() { flag.Parse() if RedisAddress != "" { //redis初始化操作 } fmt.Printf("redis address:%s\n", RedisAddress)}

          然后在命令行中進行編譯或直接運行時要指定-redis_address參數(shù),如下:
          go run main.go -redis_address=redisaddr.goxuetang.com

          隨著項目規(guī)模的增大,需要的命令行參數(shù)越來越多,假設有50個命令行參數(shù)甚至更多,如果我們一個一個指定的話,可想而知會是一件多么可怕的事情:參數(shù)多,難以維護,容易出錯。下面我們就介紹通過讓程序從配置文件中讀取的方法。


          02 通過文件讀取命令行參數(shù)的flag應用
          常規(guī)應用中,我們看到,讀取并解析命令行參數(shù)的邏輯主要在flag.Parse中。我們對flag.Parse()進一步查看,看到源碼包中flag.Parse()函數(shù)實際上是調(diào)用了CommandLine.Parse(arguments []string) error函數(shù),如下:
          func Parse() {  // Ignore errors; CommandLine is set for ExitOnError.  CommandLine.Parse(os.Args[1:])}
          通過上面代碼可知,os.Args[1:]就是命令行后跟的所有參數(shù)的集合(在上面的例子中就是 [-redis_address=redisaddr.goxuetang.com]),然后CommandLine.Parse對該字符串集合進行實際的解析。
          那我們要實現(xiàn)的目標實際上就是將文件中的每一行讀取出來,組織成CommandLine.Parse函數(shù)可接收的參數(shù)即可。如下圖所示flag常規(guī)解析和讀取文件方式的示意圖:


          好了,思路講清楚后,我們來看下代碼實現(xiàn)

          03 代碼實現(xiàn)
          我們將實現(xiàn)的函數(shù)封裝在flagx的包中,本文意圖是講解實現(xiàn)的思路,所以在代碼中忽略了錯誤處理,大家在實際項目中自行添加即可。
          package flagx
          //存儲命令行傳過來的文件路徑var FlagFile string
          func init() { //注冊命令行的flagfile參數(shù) flag.Var(&FlagFile, "flagfile", "")}
          //在Parse函數(shù)中調(diào)用,將解析到的命令行參數(shù)打印出來func visitFlag(f *flag.Flag) { fmt.Println(f.Name + "=" + f.Value.String())}
          func Parse() error { //先解析命令行中的-flagfile參數(shù) flag.Parse()
          var validFlagLines []string
          flagContents, _ := ioutil.ReadFile(FlagFile)
          configContent := string(flagContents) // 統(tǒng)一使用\n作為換行符,以便后面按分隔符分隔字符串成切片??configContent?=?strings.Replace(configContent,?"\r\n",?"\n",?-1) flagLines := strings.Split(configContent, "\n") for _, line := range flagLines { //忽略掉以 # 開頭的注釋行 if string([]rune(line)[0]) != "#" { //將每一行作為一個有效的命令行參數(shù) validFlagLines = append(validFlagLines, line) } }
          //實際執(zhí)行解析命令行參數(shù)的地方,這里就又和常規(guī)的flag調(diào)用一樣了??_?:=?flag.CommandLine.Parse(validFlagLines)??//將解析到的命令行參數(shù)都按visitFlag函數(shù)的格式輸出 flag.VisitAll(visitFlag) return nil}

          假設命令行參數(shù)文件存在于文件/data/conf/prod.gflags中,內(nèi)容如下:
          # redis地址-redis_address=redisaddr.goxuetang.com# redis端口-redis_port=9999
          # 其他所有的命令行參數(shù)

          好,接下來寫個main函數(shù)測試一下,main函數(shù)中引入的gotech.github.com/m/flagfile/flagx 包是我項目下的定義路徑,大家在實際開發(fā)中根據(jù)自己的項目組織包路徑即可。

          package mainimport (  "flag"  "fmt"  "gotech.github.com/m/flagfile/flagx")var (  RedisAddress string  RedisPort    int)
          func init() { flag.StringVar(&RedisAddress, "redis_address", "127.0.0.1", "this is redis address") flag.IntVar(&RedisPort, "redis_port", 6379, "this is redis port")}
          func main() { //這里調(diào)用我們自定實現(xiàn)的Parse函數(shù) err := flagx.Parse()??fmt.Println("err:",?err)
          if RedisAddress != "" && RedisPort != 0 { //redis初始化操作 } fmt.Printf("redis address:%s,port:%d\n", RedisAddress, RedisPort)}

          執(zhí)行如下命令
          go run main.go -flagfile=/data/conf/prod.gflags


          04 總結(jié)
          和常規(guī)的flag應用相比,將命令行參數(shù)寫在配置文件中,可以提高命令行參數(shù)的可讀性以及可維護性。該方法的實現(xiàn)思路主要是應用了flag.Parse解析命令行參數(shù)底層的CommandLine.Parse(arguments []string)的函數(shù)功能,將文件中的每行命令行參數(shù)組織成一個切片,然后調(diào)用CommandLine.Parse方法。

          推薦閱讀


          福利

          我為大家整理了一份從入門到進階的Go學習資料禮包,包含學習建議:入門看什么,進階看什么。關注公眾號 「polarisxu」,回復?ebook?獲??;還可以回復「進群」,和數(shù)萬 Gopher 交流學習。


          瀏覽 131
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  日批免费视频观看 | 日韩AV中文字幕在线免费观看 | 06久久人人 | 亚洲免费一区二区 | 亚洲精品粉嫩小泬18p图片 |