1.使用os获取简单命令行参数
根据文档中对os包的描述可得知,os的变量Args保存了命令行的参数(第一个是程序名称),因此我们不难写出一个“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)
}
但是问题来了,os.Args需要预先双方规定好如何输入,且输入都转为字符串,我们想要让程序像mysql一样接收 -u -p 这样的参数
2.使用flag解析命令行复杂参数
先看一个简单的demo,具体函数使用方法见文档
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)
}
//执行程序 go run demo.go --name=zjb
- 在[1]位置,我们利用 flag.StringVar 注册了一个 flag
- 在[2]位置,等所有flag都注册完后,调用解析函数来解析命令行参数写入注册的flag中
- 当我们执行--help时 ,获取到帮助信息 please input your name
阅读StringVal源码,实际是调用flagset 中的Var方法
func (f *FlagSet) StringVar(p *string, name string, value string, usage string) {
f.Var(newStringValue(value, p), name, usage)
}
继续查找Var源头
func Var(value Value, name string, usage string) {
CommandLine.Var(value, name, usage)
}
发现实际是调用变量CommandLine的方法
Command为何物?它是一个FlagSet,根据文档描述
CommandLine是默认的命令行flag集,用于解析os.Args
var CommandLine = NewFlagSet(os.Args[0], ExitOnError)
也就是说我们可以根据这个特性继续改造我们的程序(flagSet中有一个成员,为函数类型,用于在用户输入--help 或 参数类型错误时停止程序和抛出异常提示 )
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)
}
再简化一下
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,简介明了
3.拓展自定义类型
思路:利用Var方法,同时实现Value接口
package main
import (
"fmt"
"flag"
"os"
)
//自定义类型
type myValue struct {
p string
}
//实现接口的Set方法 负责解析传入的值
func (f *myValue) Set( v string ) error {
f.p = v
return nil
}
// 获取真正的值
func (f *myValue) String() string {
return f.p
}
// 创建类实例指针
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)
}
本文内容及代码参考:
网友评论