1.使用os獲取簡(jiǎn)單命令行參數(shù)
根據(jù)文檔中對(duì)os包的描述可得知,os的變量Args保存了命令行的參數(shù)(第一個(gè)是程序名稱),因此我們不難寫出一個(gè)“hello 用戶名”的程序
//demo1
package main
import (
"fmt"
"os"
)
var name string
func init(){
if len(os.Args)>1 {
name = os.Args[1]
} else {
name = "world"
}
}
func main(){
fmt.Printf("Hello %s!\n",name)
}
但是問(wèn)題來(lái)了,os.Args需要預(yù)先雙方規(guī)定好如何輸入,且輸入都轉(zhuǎn)為字符串,我們想要讓程序像mysql一樣接收 -u -p 這樣的參數(shù)
2.使用flag解析命令行復(fù)雜參數(shù)
先看一個(gè)簡(jiǎn)單的demo,具體函數(shù)使用方法見(jiàn)文檔
package main
import (
"fmt"
"flag"
)
var name string
func init(){
flag.StringVar(&name,"name","world","please input your name") //[1]
}
func main(){
flag.Parse() //[2]
fmt.Printf("Hello %s!\n",name)
}
//執(zhí)行程序 go run demo.go --name=zjb
- 在[1]位置,我們利用 flag.StringVar 注冊(cè)了一個(gè) flag
- 在[2]位置,等所有flag都注冊(cè)完后,調(diào)用解析函數(shù)來(lái)解析命令行參數(shù)寫入注冊(cè)的flag中
- 當(dāng)我們執(zhí)行--help時(shí) ,獲取到幫助信息 please input your name
閱讀StringVal源碼,實(shí)際是調(diào)用flagset 中的Var方法
func (f *FlagSet) StringVar(p *string, name string, value string, usage string) {
f.Var(newStringValue(value, p), name, usage)
}
繼續(xù)查找Var源頭
func Var(value Value, name string, usage string) {
CommandLine.Var(value, name, usage)
}
發(fā)現(xiàn)實(shí)際是調(diào)用變量CommandLine的方法
Command為何物?它是一個(gè)FlagSet,根據(jù)文檔描述
CommandLine是默認(rèn)的命令行flag集,用于解析os.Args
var CommandLine = NewFlagSet(os.Args[0], ExitOnError)
也就是說(shuō)我們可以根據(jù)這個(gè)特性繼續(xù)改造我們的程序(flagSet中有一個(gè)成員,為函數(shù)類型,用于在用戶輸入--help 或 參數(shù)類型錯(cuò)誤時(shí)停止程序和拋出異常提示 )
package main
import (
"fmt"
"flag"
"os"
)
var name string
func init(){
flag.CommandLine = flag.NewFlagSet("myCommand",flag.ExitOnError)
flag.CommandLine.Usage = func(){
fmt.Fprintf(os.Stderr, "Usage of %s:\n", "myCommand")
flag.PrintDefaults()
}
flag.StringVar(&name, "name", "world", "please input your name")
}
func main(){
flag.Parse()
fmt.Printf("Hello %s!\n",name)
}
再簡(jiǎn)化一下
package main
import (
"fmt"
"flag"
"os"
)
var name string
var cmdLine =flag.NewFlagSet("myCommand",flag.ExitOnError)
func init(){
cmdLine.StringVar(&name, "name", "world", "please input your name")
}
func main(){
cmdLine.Parse( os.Args[1:] )
fmt.Printf("Hello %s!\n",name)
}
ok,簡(jiǎn)介明了
3.拓展自定義類型
思路:利用Var方法,同時(shí)實(shí)現(xiàn)Value接口
package main
import (
"fmt"
"flag"
"os"
)
//自定義類型
type myValue struct {
p string
}
//實(shí)現(xiàn)接口的Set方法 負(fù)責(zé)解析傳入的值
func (f *myValue) Set( v string ) error {
f.p = v
return nil
}
// 獲取真正的值
func (f *myValue) String() string {
return f.p
}
// 創(chuàng)建類實(shí)例指針
var name *myValue = &myValue{p:"world"}
var cmdLine =flag.NewFlagSet("myCommand",flag.ExitOnError)
func init(){
cmdLine.Var(name, "name", "please input your name")
}
func main(){
cmdLine.Parse( os.Args[1:] )
fmt.Printf("Hello %s!\n",name.p)
}
本文內(nèi)容及代碼參考: