Go命令行參數(shù)解析flag 包使用示例詳解
Go]命令行參數(shù)解析包(flag 包)使用詳解
Go 的 flag 包可以解析命令行的參數(shù)。
一、命令行語法
命令行語法主要有以下幾種形式:
cmd -flag // 只支持bool類型
cmd -flag=xxx
cmd -flag xxx // 只支持非bool類型
以上語法對(duì)于一個(gè)或兩個(gè)‘-’號(hào)是一樣的,即
cmd -flag xxx (使用空格,一個(gè) - 符號(hào))
cmd --flag xxx (使用空格,兩個(gè) - 符號(hào))
cmd -flag=xxx (使用等號(hào),一個(gè) - 符號(hào))
cmd --flag=xxx (使用等號(hào),兩個(gè) - 符號(hào))
對(duì)于整形 flag,合法的值可以為 1234,0664,0x1234 或 負(fù)數(shù) 等。對(duì)于布爾型 flag,可以為 1,0,t,f,T,F(xiàn),true,false,TRUE,F(xiàn)ALSE,True,F(xiàn)alse 等
其中,布爾類型的參數(shù)比較特殊,為了防止解析時(shí)的二義性,應(yīng)該使用 等號(hào) 的方式指定
二、命令行參數(shù)方法
1.定義flag參數(shù)
參數(shù)有三個(gè):第一個(gè)為 參數(shù)名稱,第二個(gè)為 默認(rèn)值,第三個(gè)是 使用說明
1>通過 flag.String(),Bool(),Int() 等 flag.Xxx() 方法,該種方式返回一個(gè)相應(yīng)的指針
var ip = flag.Int("flagname", 1234, "help message for flagname")2>通過 flag.XxxVar() 方法將 flag 綁定到一個(gè)變量,該種方式返回 值類型,如
var flagvar intflag.IntVar(&flagvar, "flagname", 1234, "help message for flagname")
3> 通過 flag.Var() 綁定自定義類型,自定義類型需要實(shí)現(xiàn) Value 接口 (Receiver 必須為指針),如
flag.Var(&flagVal, "name", "help message for flagname")
2. 調(diào)用 flag.Parse() 解析命令行參數(shù)到定義的 flag
flag.Parse()
解析函數(shù)將會(huì)在碰到第一個(gè) 非flag 命令行參數(shù)時(shí)停止,非flag 命令行參數(shù)是指不滿足命令行語法的參數(shù),如命令行參數(shù)為 cmd --flag=true abc 則第一個(gè) 非flag 命令行參數(shù)為“abc”
3. 調(diào)用 Parse 解析后,就可以直接使用 flag 本身(指針類型)或者綁定的變量了(值類型)
fmt.Println("flagvar has value ", flagvar)還可通過 flag.Args(), flag.Arg(i) 來獲取 非flag 命令行參數(shù)!
三、實(shí)例
package main
import (
"flag"
"fmt"
)
func main() {
username := flag.String("name", "", "Input your username")
flag.Parse()
fmt.Println("Hello, ", *username)
}編譯:
go build flag.go
運(yùn)行:
./flag -name=world
輸出:
Hello, world
Go 還允許 自定義“命令行參數(shù)解析規(guī)則”,如下接口所示:
FlagSet 結(jié)構(gòu):
type FlagSet struct {
Usage func()
}示例:
package main
import (
"flag"
"fmt"
)
var myFlagSet = flag.NewFlagSet("myflagset", flag.ExitOnError)
var stringFlag = myFlagSet.String("abc", "default value", "help mesage")
func main() {
myFlagSet.Parse([]string{"-abc", "def", "ghi", "123"})
args := myFlagSet.Args()
for i := range args {
fmt.Println(i, myFlagSet.Arg(i))
}
}Go-命令行參數(shù)解析
1. 解析命令行參數(shù)
程序在執(zhí)行時(shí),獲取在命令行啟動(dòng)程序是使用的參數(shù)
- 命令行( Command line interface -- CLI):基于文本來查看、處理、操作計(jì)算機(jī)的界面,又被稱為 終端、控制臺(tái)
- 命令:在命令行執(zhí)行的程序,一般是一行,包含命令名字、子命令與命令相關(guān)的選項(xiàng)(Flag),
- Flag:傳遞給命令的參數(shù),通過參數(shù)全稱或者參數(shù)首字符指定參數(shù)名稱,參數(shù)之后使用
=或空格連接參數(shù)與參數(shù)值
2. Golang 獲取命令行參數(shù)
os.Args: 返回一個(gè)字符串slice,第一個(gè)當(dāng)前程序自身路徑,剩余參數(shù)是傳遞給命令行的參數(shù)
傳遞的參數(shù)一般是
--key=value形式 、簡寫-k value形式或者是一個(gè)開關(guān)標(biāo)志-k,使用os.Args只是獲取一個(gè)以空格分隔的字符串列表,無法很好的解析傳遞進(jìn)來的參數(shù)到變量中
package main
import (
"fmt"
"os"
)
func main() {
commandArgs := os.Args
fmt.Println(commandArgs)
}# 執(zhí)行程序: 遞歸瀏覽指定目錄下所有文件 go run main.go --name ls --value /etc -r # 輸出: [/tmp/go-build2637413899/b001/exe/main --name ls --value /etc -r]
- 命令行參數(shù)解析 -- flag包
需要知曉程序的命令行需要傳遞哪些參數(shù),如果沒有傳遞該參數(shù),那么默認(rèn)值是什么,參數(shù)的說明
使用flag的流程: 1. 初始化存放命令行參數(shù)的全局變量 2. 在main包的init函數(shù)中注冊(cè)需要解析的命令行參數(shù),包含參數(shù)的類型、參數(shù)存放到哪個(gè)變量、參數(shù)的名稱、參數(shù)的默認(rèn)值、參數(shù)的使用說明 3. 在定義解析命令行參數(shù)最后,添加 flag.Parse(),解析傳遞到程序的命令行參數(shù)到變量中 4. 主函數(shù)中通過全局變量引用命令行參 5. 運(yùn)行主函數(shù),通過 -<參數(shù)名>=<value> 或 -<參數(shù)名> <value> 方式傳參 解析命令行參數(shù)的基本文法: 1. flag.<類型>Var(<指針>, <參數(shù)名稱>, <默認(rèn)值>, <用法說明>) 2. 等價(jià)方法: flag.<類型>(<參數(shù)名稱>, <默認(rèn)值>, <用法說明>) - 區(qū)別在于,Var后綴方法是通過指針將值存放到指針指向的變量,未帶Var后綴的方法返回一個(gè)指定值的指針 - 相同的,參數(shù)值不同則使用不同的類型,都包含參數(shù)的名稱、參數(shù)的默認(rèn)值、該參數(shù)使用說明 - 類型是基本數(shù)據(jù)類型:int int64 uint uint64 string bool fl0at64 Duration
package main
import (
"flag"
"fmt"
)
// 1. 聲明保存命令行參數(shù)的變量
var (
name string
value string
isRecursive bool
)
func init() {
// 2. 注冊(cè)需要解析的命令行參: 參數(shù)名、默認(rèn)值、參數(shù)說明
flag.StringVar(&name, "name", "none", "執(zhí)行命令的名稱")
flag.StringVar(&value, "value", "none", "執(zhí)行命令的參數(shù)")
flag.BoolVar(&isRecursive, "recursive", false, "是否遞歸")
// 3. 解析命令行參數(shù)
flag.Parse()
}
func main() {
// 4. 主程序中通過全局變量引用命令行參
fmt.Println(name, value, isRecursive)
}# 輸出:ls /etc true go run main.go -name ls -value /etc -recursive # 輸出: ls /etc false go run main.go -name ls -value /etc
Flag包相關(guān)的其他方法
flag.Set()解析后修改或設(shè)置命令行參數(shù)
package main
import (
"flag"
"fmt"
)
// 1. 聲明保存命令行參數(shù)的變量
var (
name string
)
func init() {
// 2. 聲明需要解析的命令行參: 參數(shù)名、默認(rèn)值、參數(shù)說明
flag.StringVar(&name, "name", "none", "執(zhí)行命令的名稱")
// 將name的值修改為 find
flag.Set("name", "find")
}
func main() {
// 4. 主程序中通過全局變量引用命令行參
fmt.Println(name)
}# 輸出:find go run main.go -name ls
flog.NFlag()返回被設(shè)置的flag數(shù)量
package main
import (
"flag"
"fmt"
)
// 1. 聲明保存命令行參數(shù)的變量
var (
name string
value string
isRecursive bool
)
func init() {
flag.StringVar(&name, "name", "none", "執(zhí)行命令的名稱")
flag.StringVar(&value, "value", "none", "執(zhí)行命令的參數(shù)")
flag.BoolVar(&isRecursive, "recursive", false, "是否遞歸")
flag.Parse()
}
func main() {
fmt.Println("number of set flag:", flag.NFlag())
}# 輸出:number of set flag: 2
go run main.go -name ls -value /etc
flag,Parsed()檢查flag.Parse()是否被調(diào)用過
package main
import (
"flag"
"fmt"
)
// 1. 聲明保存命令行參數(shù)的變量
var (
name string
value string
isRecursive bool
)
func init() {
flag.StringVar(&name, "name", "none", "執(zhí)行命令的名稱")
flag.StringVar(&value, "value", "none", "執(zhí)行命令的參數(shù)")
flag.BoolVar(&isRecursive, "recursive", false, "是否遞歸")
flag.Parse()
}
func main() {
fmt.Println("is Parsed", flag.Parsed())
}# 輸出:is Parsed true
go run main.go -name ls -value /etc
flag.Visit(func (*Flag))按字典順序遍歷,進(jìn)行設(shè)置了的標(biāo)簽
package main
import (
"flag"
"fmt"
)
// 1. 聲明保存命令行參數(shù)的變量
var (
name string
value string
isRecursive bool
)
func init() {
flag.StringVar(&name, "name", "none", "執(zhí)行命令的名稱")
flag.StringVar(&value, "value", "none", "執(zhí)行命令的參數(shù)")
flag.BoolVar(&isRecursive, "recursive", false, "是否遞歸")
flag.Parse()
}
func main() {
flag.Visit(func(f *flag.Flag) {
fmt.Printf("Name: %s, Value: %s, DefValue: %s, Usage: %s \n", f.Name, f.Value, f.DefValue, f.Usage)
})
}# 輸出:
# Name: name, Value: ls, DefValue: none, Usage: 執(zhí)行命令的名稱
# Name: value, Value: /etc, DefValue: none, Usage: 執(zhí)行命令的參數(shù)
go run main.go -name ls -value /etc
到此這篇關(guān)于Go-命令行參數(shù)解析的文章就介紹到這了,更多相關(guān)Go命令行參數(shù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Go語言標(biāo)準(zhǔn)庫sync.Once使用場(chǎng)景及性能優(yōu)化詳解
這篇文章主要為大家介紹了Go語言標(biāo)準(zhǔn)庫sync.Once使用場(chǎng)景及性能優(yōu)化詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-12-12
使用go實(shí)現(xiàn)刪除sql里面的注釋和字符串功能(demo)
這篇文章主要介紹了使用go實(shí)現(xiàn)刪除sql里面的注釋和字符串功能,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-11-11
Golang命令行進(jìn)行debug調(diào)試操作
今天小編就為大家分享一篇關(guān)于,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧2019-04-04
golang?channel多協(xié)程通信常用方法底層原理全面解析
channel?是?goroutine?與?goroutine?之間通信的重要橋梁,借助?channel,我們能很輕易的寫出一個(gè)多協(xié)程通信程序,今天,我們就來看看這個(gè)?channel?的常用用法以及底層原理2023-09-09
Go語言服務(wù)器開發(fā)之客戶端向服務(wù)器發(fā)送數(shù)據(jù)并接收返回?cái)?shù)據(jù)的方法
這篇文章主要介紹了Go語言服務(wù)器開發(fā)之客戶端向服務(wù)器發(fā)送數(shù)據(jù)并接收返回?cái)?shù)據(jù)的方法,實(shí)例分析了客戶端的開發(fā)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-02-02
Go?Ginrest實(shí)現(xiàn)一個(gè)RESTful接口
這篇文章主要為大家介紹了Go?Ginrest實(shí)現(xiàn)一個(gè)RESTful接口示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08

