Go36-2-flag包

解析命令行參數(shù)

Go語言標準庫中的flag包專門用于接收和解析命令參數(shù)。

創(chuàng)新互聯(lián)長期為1000+客戶提供的網(wǎng)站建設服務,團隊從業(yè)經(jīng)驗10年,關注不同地域、不同群體,并針對不同對象提供差異化的產(chǎn)品和服務;打造開放共贏平臺,與合作伙伴共同營造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為肅寧企業(yè)提供專業(yè)的成都網(wǎng)站建設、網(wǎng)站建設,肅寧網(wǎng)站改版等技術服務。擁有十載豐富建站經(jīng)驗和眾多成功案例,為您定制開發(fā)。

基本用法

從命令行接收參數(shù)并打印出來:

package main

import (
    "flag"
    "fmt"
)

var name string

func init() {
    flag.StringVar(&name, "name", "Nobody", "請設置名字")
}

func main() {
    flag.Parse()
    fmt.Printf("Hello, %s!\n", name)
}

函數(shù)flag.StringVar接受4個參數(shù):

  • 第1個參數(shù),是用于存儲該命令參數(shù)的值的地址,就是示例中聲明的變量name的地址,由表達式&name表示
  • 第2個參數(shù),是為了指定該命令參數(shù)的名稱,這里是name
  • 第3個參數(shù),是為了指定在未追加該命令參數(shù)時的默認值,這里是Nobody
  • 第4個參數(shù),是該命令參數(shù)的簡短說明,這在打印命令說明時會用到

還有一個函數(shù)flag.String和flag.StringVar類似。就是沒有第一個參數(shù)了,而是直接返回一個已經(jīng)分配好的用于存儲命令參數(shù)值的地址。

package main

import (
    "flag"
    "fmt"
)

var name string

func init() {
    name = *flag.String("name", "Nobody", "請設置名字")
}

func main() {
    flag.Parse()
    fmt.Printf("Hello, %s!\n", name)
}

函數(shù)調(diào)用順序

函數(shù)flag.Parse用于真正解析命令參數(shù),并把它們的值賦給相應的變量。
該函數(shù)的調(diào)用必須在所有命令參數(shù)的聲明和設置之后,并且在讀取任何命令參數(shù)值之前。
也就是像例子里做的,把參數(shù)設置的語句放在init函數(shù)里先執(zhí)行,然后把flag.Parse放在main函數(shù)的開頭,在調(diào)用使用命令行參數(shù)的語句之前。

自定制參數(shù)使用說明

在上面的例子中,執(zhí)行的時候帶上-h或者--help參數(shù),就能看到如下的使用說明:

PS G:\Steed\Documents\Go\src\Go36\article02\example01> go run main.go --help
Usage of C:\Users\Steed\AppData\Local\Temp\go-build897600374\command-line-arguments\_obj\exe\main.exe:
  -name string
        請設置名字 (default "Nobody")
exit status 2
PS G:\Steed\Documents\Go\src\Go36\article02\example01>

輸出的第一行在Usage of后面一長串的路徑,是go run命令構(gòu)建上述命令源碼文件時臨時生成的可執(zhí)行文件的完整路徑。如果是編譯之后再執(zhí)行,就是可執(zhí)行文件的相對路徑,就沒那么難看了。
并且這一行的說明內(nèi)容是可以自定制的,接下來就是通過包提供的方法對這行說明進行自定制。這3種方法是一層一層更加接近底層的調(diào)用的。

通過flag.Usage定制

最簡單的一種定制方式就是對變量flag.Usage重新賦值。為該變量定義一個函數(shù),在要打印說明的時候,其實就是調(diào)用執(zhí)行了這個方法:

package main

import (
    "flag"
    "fmt"
    "os"
)

var name string

func init() {
    // 下面2句語句的順序隨意
    flag.StringVar(&name, "name", "Nobody", "請設置名字")
    flag.Usage = func() {
        fmt.Fprintf(os.Stderr, "Usage of %s\n", "Say Hello")
        flag.PrintDefaults()
    }
}

func main() {
    flag.Parse()
    fmt.Printf("Hello, %s!\n", name)
}

flag.Usage的賦值必須在調(diào)用flag.Parse()之前。

通過flag.CommandLine定制

在調(diào)用flag包中的一些函數(shù)(比如StringVar、Parse等等)的時候,實際上是在調(diào)用flag.CommandLine變量的對應方法。
flag.CommandLine相當于默認情況下的命令參數(shù)容?。通過對flag.CommandLine重新賦值,就可以更深層次地定制當前命令源碼文件的參數(shù)使用說明。
僅修改之前的init函數(shù)部分,去掉flag.Usage的賦值語句,改為通過對flag.CommandLine賦值來進行定制:

func init() {
    // flag.CommandLine對象的創(chuàng)建必須在前面執(zhí)行
    flag.CommandLine = flag.NewFlagSet("", flag.ExitOnError)
    //flag.CommandLine = flag.NewFlagSet("", flag.PanicOnError)
    flag.CommandLine.Usage = func() {
        fmt.Fprintf(os.Stderr, "Usage of %s\n", "Say Hello")
        flag.PrintDefaults()
    }
    flag.StringVar(&name, "name", "Nobody", "請設置名字")
}

這樣修改后的效果和之前完全一致。這里主要出分離出了下面這句:

flag.CommandLine = flag.NewFlagSet("", flag.ExitOnError)

這句的第一個參數(shù)應該是沒有用的了,這里傳入空字符串。
第二個參數(shù)可以是一下的3個常量:

const (
    ContinueOnError ErrorHandling = iota // Return a descriptive error.
    ExitOnError                          // Call os.Exit(2).
    PanicOnError                         // Call panic with a descriptive error.
)

定義在解析遇到問題后,是執(zhí)行何種操作。默認的就是ExitOnError,所以在--help執(zhí)行打印說明后,最后一行會出現(xiàn)“exit status 2”,以狀態(tài)碼2退出。
這里可以根據(jù)需要定制為拋出Panic。

創(chuàng)建私有命令參數(shù)容器

這里的代碼上上面的例子差不多,依然是調(diào)用flag.NewFlagSet()創(chuàng)建命令參數(shù)容器。不過這次把容器賦值給自定義的變量:

package main

import (
    "flag"
    "fmt"
    "os"
)

var name string
var cmdLine = flag.NewFlagSet("cmdLine Say Hello", flag.ExitOnError)

func init() {
    cmdLine.StringVar(&name, "name", "Nobody", "請設置名字")
}

func main() {
    cmdLine.Parse(os.Args[1:])
    fmt.Printf("Hello, %s!\n", name)
}

首先通過命令 var cmdLine = flag.NewFlagSet("cmdLine Say Hello", flag.ExitOnError) 創(chuàng)建了私有的命令參數(shù)容器。
然后,之后其他所有方法的調(diào)用都通過這個變量來調(diào)用的。
上面這樣做之后,就完全脫離了flag.CommandLine。而是使用 *flag.FlagSet 類型的變量 cmdLine 進行各種調(diào)用了。該類型擁有很多方法,可以繼續(xù)探索。
主要是可以更靈活地定制命令參數(shù)容?。并且你的定制完全不會影響到全局變量flag.CommandLine。

當前名稱:Go36-2-flag包
瀏覽路徑:http://m.kartarina.com/article26/gechcg.html

成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供網(wǎng)頁設計公司企業(yè)建站網(wǎng)站設計公司、響應式網(wǎng)站、做網(wǎng)站、企業(yè)網(wǎng)站制作

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

商城網(wǎng)站建設
主站蜘蛛池模板: 国产50部艳色禁片无码| 日韩免费无码一区二区视频| 蜜芽亚洲av无码精品色午夜| 国产AV无码专区亚洲AV毛网站| 无码少妇一区二区浪潮免费| 国产午夜无码福利在线看网站 | 无码人妻精品一区二区三区蜜桃 | 亚洲熟妇无码av另类vr影视| 精品无码久久久久久久久| 久久久久久AV无码免费网站| 免费无码AV一区二区| 人妻丰满熟妇AV无码区乱| 国产精品一区二区久久精品无码| 91久久精品无码一区二区毛片| 久久久久久av无码免费看大片| 亚洲精品无码人妻无码| 亚洲AV无码乱码在线观看裸奔| 国产丝袜无码一区二区视频| 亚洲av无码一区二区三区人妖| 亚洲国产超清无码专区| 在线播放无码高潮的视频| 精品国产毛片一区二区无码| 蜜臀亚洲AV无码精品国产午夜.| 免费无码又爽又刺激高潮视频| 中文字幕AV中文字无码亚| 久久久精品无码专区不卡| 亚洲?V无码成人精品区日韩| 精品亚洲av无码一区二区柚蜜| 亚洲成无码人在线观看| 亚洲av无码片在线观看| 精品无码久久久久国产动漫3d| 精品人妻系列无码一区二区三区| 无码AV片在线观看免费| 日日麻批免费40分钟无码| 无码人妻一区二区三区在线| 午夜福利无码不卡在线观看| 无码国产精品一区二区免费3p | 日韩精品无码人成视频手机 | 亚洲av永久无码精品三区在线4| 亚洲AV无码久久精品蜜桃| 免费A级毛片无码专区|