中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Go36-2-flag包

發布時間:2020-06-17 13:08:27 來源:網絡 閱讀:298 作者:騎士救兵 欄目:編程語言

解析命令行參數

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

基本用法

從命令行接收參數并打印出來:

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)
}

函數flag.StringVar接受4個參數:

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

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

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)
}

函數調用順序

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

自定制參數使用說明

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

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命令構建上述命令源碼文件時臨時生成的可執行文件的完整路徑。如果是編譯之后再執行,就是可執行文件的相對路徑,就沒那么難看了。
并且這一行的說明內容是可以自定制的,接下來就是通過包提供的方法對這行說明進行自定制。這3種方法是一層一層更加接近底層的調用的。

通過flag.Usage定制

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

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的賦值必須在調用flag.Parse()之前。

通過flag.CommandLine定制

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

func init() {
    // flag.CommandLine對象的創建必須在前面執行
    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)

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

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

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

創建私有命令參數容器

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

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) 創建了私有的命令參數容器。
然后,之后其他所有方法的調用都通過這個變量來調用的。
上面這樣做之后,就完全脫離了flag.CommandLine。而是使用 *flag.FlagSet 類型的變量 cmdLine 進行各種調用了。該類型擁有很多方法,可以繼續探索。
主要是可以更靈活地定制命令參數容?。并且你的定制完全不會影響到全局變量flag.CommandLine。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

应用必备| 米泉市| 呼图壁县| 湘潭市| 株洲县| 桐乡市| 开鲁县| 林周县| 马关县| 绍兴市| 台南市| 东乌| 利津县| 安国市| 三门县| 石渠县| 女性| 河曲县| 张家界市| 油尖旺区| 珲春市| 中卫市| 西和县| 中西区| 塔城市| 正宁县| 陆川县| 翁源县| 垣曲县| 顺平县| 郴州市| 项城市| 黄大仙区| 雅安市| 延津县| 镇宁| 广元市| 肥东县| 峨山| 嘉荫县| 盐津县|