Go语言flag包:令行参数解析
下面我们就来看一下 flag 包可以做什么,它具有什么样的能力。
这里介绍几个概念:
令行参数(或参数):是指运行程序时提供的参数;
已定义令行参数:是指程序中通过 flag.Type 这种形式定义了的参数;
非 flag(non-flag)令行参数(或保留的令行参数):可以简单理解为 flag 包不能解析的参数。
flag 包概述
Go语言内置的 flag 包实现了令行参数的解析,flag 包使得开发令行工具更为简单。若要使用 flag 包,首先需要使用 import 关键字导入 flag 包,如下所示:import "flag"
flag 参数类型
flag 包支持的令行参数类型有 bool、int、int64、uint、uint64、float、float64、string、duration,如下表所示:flag 参数 | 有效值 |
|---|---|
字符串 flag | 法字符串 |
整数 flag | 1234、0664、0x1234 等类型,也可以是负数 |
浮点数 flag | 法浮点数 |
bool 类型 flag | 1、0、t、f、T、F、true、false、TRUE、FALSE、True、False |
时间段 flag | 任何法的时间段字符串,如“300ms”、“-1.5h”、“2h45m”, 法的单位有“ns”、“us”、“µs”、“ms”、“s”、“m”、“h” |
flag 包基本使用
有以下两种常用的定义令行 flag 参数的方法:1) flag.Type()
基本格式如下:flag.Type(flag 名, 默认值, 帮助信息) *Type
Type 可以是 Int、String、Bool 等,返回值为一个相应类型的指针,例如我们要定义姓名、年龄、婚否三个令行参数,我们可以按如下方式定义:
需要注意的是,此时 name、age、married、delay 均为对应类型的指针。name := flag.String("name", "张三", "姓名")
age := flag.Int("age", 18, "年龄")
married := flag.Bool("married", false, "婚否")
delay := flag.Duration("d", 0, "时间间隔")
2) flag.TypeVar()
基本格式如下:
flag.TypeVar(Type 指针, flag 名, 默认值, 帮助信息)
TypeVar 可以是 IntVar、StringVar、BoolVar 等,其功能为将 flag 绑定到一个变量上,例如我们要定义姓名、年龄、婚否三个令行参数,我们可以按如下方式定义:var name string
var age int
var married bool
var delay time.Duration
flag.StringVar(&name, "name", "张三", "姓名")
flag.IntVar(&age, "age", 18, "年龄")
flag.BoolVar(&married, "married", false, "婚否")
flag.DurationVar(&delay, "d", 0, "时间间隔")
flag.Parse()
通过以上两种方法定义好令行 flag 参数后,需要通过调用 flag.Parse() 来对令行参数进行解析。支持的令行参数格式有以下几种:
-flag:只支持 bool 类型;
-flag=x;
-flag x:只支持非 bool 类型。
其中,布尔类型的参数必须使用等号的方式指定。
flag 包的其他函数:
flag.Args() //返回令行参数后的其他参数,以 []string 类型
flag.NArg() //返回令行参数后的其他参数个数
flag.NFlag() //返回使用的令行参 数个数
结上面的介绍知识,我们来看一个实例,代码如下:
package main
import (
"flag"
"fmt"
)
var Input_pstrName = flag.String("name", "gerry", "input ur name")
var Input_piAge = flag.Int("age", 20, "input ur age")
var Input_flagvar int
func Init() {
flag.IntVar(&Input_flagvar, "flagname", 1234, "help message for flagname")
}
func main() {
Init()
flag.Parse()
// After parsing, the arguments after the flag are available as the slice flag.Args() or individually as flag.Arg(i). The arguments are indexed from 0 through flag.NArg()-1
// Args returns the non-flag command-line arguments
// NArg is the number of arguments remaining after flags have been processed
fmt.Printf("args=%s, num=%d\n", flag.Args(), flag.NArg())
for i := 0; i != flag.NArg(); i++ {
fmt.Printf("arg[%d]=%s\n", i, flag.Arg(i))
}
fmt.Println("name=", *Input_pstrName)
fmt.Println("age=", *Input_piAge)
fmt.Println("flagname=", Input_flagvar)
}
运行结果如下:
go run main.go -name "aaa" -age=123 -flagname=999
args=[], num=0
name= aaa
age= 123
flagname= 999
自定义 Value
另外,我们还可以创建自定义 flag,只要实现 flag.Value 接口即可(要求 receiver 是指针类型),这时候可以通过如下方式定义该 flag:flag.Var(&flagVal, "name", "help message for flagname")
【示例】解析喜欢的编程语言,并直接解析到 slice 中,我们可以定义如下 sliceValue 类型,然后实现 Value 接口:通过package main
import (
"flag"
"fmt"
"strings"
)
//定义一个类型,用于增加该类型方法
type sliceValue []string
//new一个存放令行参数值的slice
func newSliceValue(vals []string, p *[]string) *sliceValue {
*p = vals
return (*sliceValue)(p)
}
/*
Value接口:
type Value interface {
String() string
Set(string) error
}
实现flag包中的Value接口,将令行接收到的值用,分隔存到slice里
*/
func (s *sliceValue) Set(val string) error {
*s = sliceValue(strings.Split(val, ","))
return nil
}
//flag为slice的默认值default is me,和return返回值没有关系
func (s *sliceValue) String() string {
*s = sliceValue(strings.Split("default is me", ","))
return "It's none of my business"
}
/*
可执行文件名 -slice="java,go" 将输出[java,go]
可执行文件名 将输出[default is me]
*/
func main(){
var languages []string
flag.Var(newSliceValue([]string{}, &languages), "slice", "I like programming `languages`")
flag.Parse()
//打印结果slice接收到的值
fmt.Println(languages)
}
-slice go,php 这样的形式传递参数,languages 得到的就是 [go, php],如果不加-slice 参数则打印默认值[default is me],如下所示:go run main.go -slice go,php,java
[go php java]
flag 中对 Duration 这种非基本类型的支持,使用的就是类似这样的方式,即同样实现了 Value 接口。
- 随机文章
- 帕劳 马尔代夫 性价比(探寻帕劳和马尔代夫的性价比之旅)
- 去马尔代夫要签证(前往马尔代夫游玩需办理签证,长度。)
- 中国女星马尔代夫(中国女演员赴马尔代夫度假引网友热议)
- 去马尔代夫莉莉岛(马尔代夫梦幻度假胜地莉莉岛等你来!)
- 滑道 马尔代夫(探秘马尔代夫深度旅游)
- 南昌马尔代夫露营(南昌露营团奔赴马尔代夫体验海岛露营)
- 陈豪 马尔代夫(陈豪和妻子马尔代夫游玩放松)
- 港警 马尔代夫(警方驻马警嗅辨 顺利抓获涉恐嫌犯)
- 清远 马尔代夫(清远居民在马尔代夫度假的故事)
- 快艇 马尔代夫(快艇探寻马尔代夫风光)
- 枝江有马尔代夫吗(枝江是否有类似马尔代夫的旅游胜地?)
- 南昌马尔代夫自驾(自驾游南昌和马尔代夫:探索两地风情)
- 宜兴 马尔代夫(宜兴打造“马尔代夫”般美丽景色)
- 护士鲨鱼马尔代夫(马尔代夫惊现护士鲨鱼,游客安全存忧)
- 曼谷周边马尔代夫(曼谷邻近马尔代夫,成为度假热门之地)
- 桐庐 马尔代夫(桐庐产业扶贫远航马尔代夫项目启动)
- 漳州马尔代夫景点(探索漳州马尔代夫景点,感受海岛风情)
- 悉尼直飞马尔代夫(直飞马尔代夫,探访印度洋里的天堂!)
- 玉林马尔代夫灯光(玉林马代重现!夜晚灯光增添浪漫场景)
- 迪拜马尔代夫对比(迪拜和马尔代夫:一场度假胜地的对决)
- 试吃马尔代夫美食(马尔代夫口感盛宴:尝试当地美味佳肴)
- 福建野生马尔代夫(福建神秘海滩:野生马尔代夫等你探索)
- 海上旅游马尔代夫(探索梦幻蓝海,畅游马尔代夫海上旅游)
- 迪拜马尔代夫多远(后的新为:从迪拜到马尔代夫有多远?)
- 雅高 马尔代夫(雅高集团开设马尔代夫酒店,探寻天堂岛屿风情)
- 搓麻 马尔代夫(马尔代夫风光无限,旅游新体验在搓麻游戏中!)
- 马尔代夫卡吉几星(卡吉岛:远离尘嚣的马尔代夫度假胜地)
- 马尔代夫出线预测(马尔代夫或许能够出线,世界足坛震惊)
- 国足马尔代夫炎热(国足全力备战烈日炎炎的马尔代夫赛事)
- 马尔代夫什么好喝(马尔代夫出品,这些饮品你一定要尝!)
