os 包中有一個(gè) string 類(lèi)型的切片變量 os.Args,用來(lái)處理一些基本的命令行參數(shù),它在程序啟動(dòng)后讀取命令行輸入的參數(shù)。來(lái)看下面的打招呼程序:
示例 12.11 os_args.go:
// os_args.go
package main
import (
"fmt"
"os"
"strings"
)
func main() {
who := "Alice "
if len(os.Args) > 1 {
who += strings.Join(os.Args[1:], " ")
}
fmt.Println("Good Morning", who)
}
我們?cè)?IDE 或編輯器中直接運(yùn)行這個(gè)程序輸出:Good Morning Alice
我們?cè)诿钚羞\(yùn)行 os_args or ./os_args 會(huì)得到同樣的結(jié)果。
但是我們?cè)诿钚屑尤雲(yún)?shù),像這樣:os_args John Bill Marc Luke,將得到這樣的輸出:Good Morning Alice John Bill Marc Luke
這個(gè)命令行參數(shù)會(huì)放置在切片 os.Args[] 中(以空格分隔),從索引1開(kāi)始(os.Args[0] 放的是程序本身的名字,在本例中是 os_args)。函數(shù) strings.Join 以空格為間隔連接這些參數(shù)。
練習(xí) 12.5:hello_who.go
寫(xiě)一個(gè)"Hello World"的變種程序:把人的名字作為程序命令行執(zhí)行的一個(gè)參數(shù),比如: hello_who Evan Michael Laura 那么會(huì)輸出Hello Evan Michael Laura!
flag 包有一個(gè)擴(kuò)展功能用來(lái)解析命令行選項(xiàng)。但是通常被用來(lái)替換基本常量,例如,在某些情況下我們希望在命令行給常量一些不一樣的值。(參看 19 章的項(xiàng)目)
在 flag 包中有一個(gè) Flag 被定義成一個(gè)含有如下字段的結(jié)構(gòu)體:
type Flag struct {
Name string // name as it appears on command line
Usage string // help message
Value Value // value as set
DefValue string // default value (as text); for usage message
}
下面的程序 echo.go 模擬了 Unix 的 echo 功能:
package main
import (
"flag" // command line option parser
"os"
)
var NewLine = flag.Bool("n", false, "print newline") // echo -n flag, of type *bool
const (
Space = " "
Newline = "\n"
)
func main() {
flag.PrintDefaults()
flag.Parse() // Scans the arg list and sets up flags
var s string = ""
for i := 0; i < flag.NArg(); i++ {
if i > 0 {
s += " "
if *NewLine { // -n is parsed, flag becomes true
s += Newline
}
}
s += flag.Arg(i)
}
os.Stdout.WriteString(s)
}
flag.Parse() 掃描參數(shù)列表(或者常量列表)并設(shè)置 flag, flag.Arg(i) 表示第i個(gè)參數(shù)。Parse() 之后 flag.Arg(i) 全部可用,flag.Arg(0) 就是第一個(gè)真實(shí)的 flag,而不是像 os.Args(0) 放置程序的名字。
flag.Narg() 返回參數(shù)的數(shù)量。解析后 flag 或常量就可用了。
flag.Bool() 定義了一個(gè)默認(rèn)值是 false 的 flag:當(dāng)在命令行出現(xiàn)了第一個(gè)參數(shù)(這里是 "n"),flag 被設(shè)置成 true(NewLine 是 *bool 類(lèi)型)。flag 被解引用到 *NewLine,所以當(dāng)值是 true 時(shí)將添加一個(gè) Newline("\n")。
flag.PrintDefaults() 打印 flag 的使用幫助信息,本例中打印的是:
-n=false: print newline
flag.VisitAll(fn func(*Flag)) 是另一個(gè)有用的功能:按照字典順序遍歷 flag,并且對(duì)每個(gè)標(biāo)簽調(diào)用 fn (參考 15.8 章的例子)
當(dāng)在命令行(Windows)中執(zhí)行:echo.exe A B C,將輸出:A B C;執(zhí)行 echo.exe -n A B C,將輸出:
A
B
C
每個(gè)字符的輸出都新起一行,每次都在輸出的數(shù)據(jù)前面打印使用幫助信息:-n=false: print newline。
對(duì)于 flag.Bool 你可以設(shè)置布爾型 flag 來(lái)測(cè)試你的代碼,例如定義一個(gè) flag processedFlag:
var processedFlag = flag.Bool("proc", false, "nothing processed yet")
在后面用如下代碼來(lái)測(cè)試:
if *processedFlag { // found flag -proc
r = process()
}
要給 flag 定義其它類(lèi)型,可以使用 flag.Int(),flag.Float64(),flag.String()。
在第 15.8 章你將找到一個(gè)具體的例子。