1. 参数解析说明

import "flag"

flag 包实现了命令行参数的解析。每个参数认为一条记录,根据实际进行定义,到一个 set 集合。每条都有各自的状态参数。

使用 flag 的正常流程为:

  1. 通过 flag.String()flag.Bool()flag.Int() 等函数来定义命令行中需要使用的参数;
  2. 在定义完 flag 命令行参数后,通过调用 flag.Parse() 来进行对命令行参数的解析;
  3. 获取 flag.String()flag.Bool()flag.Int() 等方法的返回值,即对应用户输入的参数;

需要注意的是:

  • flag.Xxx() 返回的值是变量的内存地址,要获取值时要通过在变量前加 * 获取。

flag.Intflag.Boolflag.String 这样的函数格式都是一样的,调用的时候需要传入 3 个参数

func Int(name string, value int, usage string) *int
func Bool(name string, value bool, usage string) *bool
func String(name string, value string, usage string) *string

name 表示命令行参数的名称, value 表示命令行参数的值, usage 表示命令行参数的说明和描述。
其它可注册的 flag 类型有:
Bool / Int / Int64 / Uint / Uint64 / Float / Float64 / String / Duration / Var

最简单的代码示例:

package main// 导入系统包
import ("flag""fmt"
)// 定义命令行参数
var mode = flag.String("mode", "", "process mode")
var num = flag.Int("num", 5, "process number")
var isProcess = flag.Bool("isProcess", true, "process bool")func main() {// 解析命令行参数flag.Parse()// 输出命令行参数fmt.Println(*mode)fmt.Println(*num)fmt.Println(*isProcess)
}

运行结果:

wohu@wohu:~/gocode/src$ go run hello.go -h
Usage of /tmp/go-build314506183/b001/exe/hello:-isProcessprocess bool (default true)-mode stringprocess mode-num intprocess number (default 5)
exit status 2
wohu@wohu:~/gocode/src$ go run hello.go  -mode="hello,world" -num=10
hello,world
10
true
wohu@wohu:~/gocode/src$

命令行 flag 语法:

-flag
-flag=x
-flag x  // 只有非bool类型的flag可以

可以使用 1 个或 2 个 - 号,效果是一样的。最后一种格式不能用于 bool 类型的 flag ,因为如果有文件名为 0、 false 等时,如下命令:

cmd -x *

其含义会改变。你必须使用 -flag=false 格式来关闭一个 bool 类型 flag
整数flag接受1234、0664、0x1234等类型,也可以是负数。bool类型flag可以是:

1, 0, t, f, T, F, true, false, TRUE, FALSE, True, False

注意: go run hello.go -mode="hello,world" -num=10 命令行中,可以是 --num=10 但不能是 --num==10

2. 数据结构和函数

2.1 type Flag

type Flag struct {Name     string // flag在命令行中的名字Usage    string // 帮助信息Value    Value  // 要设置的值DefValue string // 默认值(文本格式),用于使用信息
}

Flag 类型代表一条 flag 的状态。

2.2 type FlagSet

type FlagSet struct {// Usage函数在解析flag出现错误时会被调用// 该字段为一个函数(而非采用方法),以便修改为自定义的错误处理函数Usage func()// 内含隐藏或非导出字段
}

FlagSet 代表一个已注册的 flag 的集合。 FlagSet 零值没有名字,采用 ContinueOnError 错误处理策略。

flag 包中,进行了进一步封装:将 FlagSet 的方法都重新定义了一遍,也就是提供了一序列函数,而函数中只是简单的调用已经实例化好了的 FlagSet

所以我们只需要关注 flag 中的函数即可,它会自动调用 FlagSet 中的函数。

2.3 func NFlag

func NFlag() int

NFlag 返回已被设置的 flag 的数量。

2.4 func Lookup

func Lookup(name string) *Flag

返回已经已注册 flagFlag 结构体指针;如果 flag 不存在的话,返回 nil

2.5 func NArg

func NArg() int

NArg 返回解析 flag 之后剩余参数的个数。

2.6 func Args

func Args() []string

返回解析之后剩下的非 flag 参数。(不包括命令名)也就是说无法进行flag匹配的有哪些参数。

2.7 func Arg

func Arg(i int) string

返回解析之后剩下的第 i 个参数,从 0 开始索引。

2.8 func PrintDefaults

func PrintDefaults()

PrintDefault 会向标准错误输出写入所有注册好的 flag 的默认值。

2.9 func Bool

func Bool(name string, value bool, usage string) *bool

Bool 用指定的名称、默认值、使用信息注册一个 bool 类型 flag 。返回一个保存了该 flag 的值的指针。

2.10 func BoolVar

func BoolVar(p *bool, name string, value bool, usage string)

BoolVar 用指定的名称、默认值、使用信息注册一个 bool 类型 flag ,并将 flag 的值保存到 p 指向的变量。

2.11 func Int

func Int(name string, value int, usage string) *int

Int 用指定的名称、默认值、使用信息注册一个 int 类型 flag 。返回一个保存了该 flag 的值的指针。

2.12 func IntVar

func IntVar(p *int, name string, value int, usage string)

IntVar 用指定的名称、默认值、使用信息注册一个 int 类型 flag ,并将 flag 的值保存到 p 指向的变量。

2.13 func Int64

func Int64(name string, value int64, usage string) *int64

Int64 用指定的名称、默认值、使用信息注册一个 int64 类型 flag 。返回一个保存了该 flag 的值的指针。

2.14 func Int64Var

func Int64Var(p *int64, name string, value int64, usage string)

Int64Var 用指定的名称、默认值、使用信息注册一个 int64 类型 flag ,并将 flag 的值保存到 p 指向的变量。

2.15 func Uint

func Uint(name string, value uint, usage string) *uint

Uint 用指定的名称、默认值、使用信息注册一个 uint 类型 flag 。返回一个保存了该 flag 的值的指针。

2.16 func UintVar

func UintVar(p *uint, name string, value uint, usage string)

UintVar 用指定的名称、默认值、使用信息注册一个 uint 类型 flag ,并将 flag 的值保存到 p 指向的变量。

2.17 func Uint64

func Uint64(name string, value uint64, usage string) *uint64

Uint64 用指定的名称、默认值、使用信息注册一个 uint64 类型 flag 。返回一个保存了该 flag 的值的指针。

2.18 func Uint64Var

func Uint64Var(p *uint64, name string, value uint64, usage string)

Uint64Var 用指定的名称、默认值、使用信息注册一个 uint64 类型 flag ,并将 flag 的值保存到 p 指向的变量。

2.19 func Float64

func Float64(name string, value float64, usage string) *float64

Float64 用指定的名称、默认值、使用信息注册一个 float64 类型 flag 。返回一个保存了该 flag 的值的指针。

2.20 func Float64Var

func Float64Var(p *float64, name string, value float64, usage string)

Float64Var 用指定的名称、默认值、使用信息注册一个 float64 类型 flag ,并将 flag 的值保存到 p 指向的变量。

2.21 func String

func String(name string, value string, usage string) *string

String 用指定的名称、默认值、使用信息注册一个 string 类型 flag 。返回一个保存了该 flag 的值的指针。

2.22 func StringVar

func StringVar(p *string, name string, value string, usage string)

StringVar 用指定的名称、默认值、使用信息注册一个 string 类型 flag ,并将 flag 的值保存到 p 指向的变量。

2.23 func Duration

func Duration(name string, value time.Duration, usage string) *time.Duration

Duration 用指定的名称、默认值、使用信息注册一个 time.Duration 类型 flag 。返回一个保存了该 flag 的值的指针。

2.24 func DurationVar

func DurationVar(p *time.Duration, name string, value time.Duration, usage string)

DurationVar 用指定的名称、默认值、使用信息注册一个 time.Duration 类型 flag ,并将 flag 的值保存到 p 指向的变量。

2.25 func Var

func Var(value Value, name string, usage string)

Var 方法使用指定的名字、使用信息注册一个 flag 。该 flag 的类型和值由第一个参数表示,该参数应实现了 Value 接口。例如,用户可以创建一个 flag ,可以用 Value 接口的 Set 方法将逗号分隔的字符串转化为字符串切片。

2.26 func Set

func Set(name, value string) error

设置已注册的 flag 的值。

2.27 func Parse

func Parse()

os.Args[1:] 中解析注册的 flag 。必须在所有 flag 都注册好而未访问其值时执行。未注册却使用 flag -help 时,会返回 ErrHelp

2.28 func Parsed

func Parsed() bool

返回是否 Parse 已经被调用过。

2.29 func Visit

func Visit(fn func(*Flag))

按照字典顺序遍历标签,并且对每个标签调用 fn 。 这个函数只遍历解析时进行了设置的标签。

2.30 func VisitAll

func VisitAll(fn func(*Flag))

按照字典顺序遍历标签,并且对每个标签调用 fn 。 这个函数会遍历所有标签,不管解析时有无进行设置。

3. 代码示例

3.1 解析 flag 参数为指针

package mainimport ("flag""fmt"
)// 定义命令行参数
var mode = flag.String("mode", "", "process mode")
var num = flag.Int("num", 5, "process number")
var isProcess = flag.Bool("isProcess", true, "process bool")func main() {// 未解析时查看已设置的 flag 数量registerNum := flag.NFlag()fmt.Printf("Before Parse registerNum is %#v\n", registerNum)// Before Parse registerNum is 0// 解析命令行参数flag.Parse()registerNum = flag.NFlag()fmt.Printf("After Parse registerNum is %#v\n", registerNum)// After Parse registerNum is 3// 无法进行flag匹配的有哪些参数flagArgs := flag.Args()fmt.Printf("flagArgs is %#v\n", flagArgs)// 输出命令行参数fmt.Println(*mode)    // 必须加 * 号fmt.Println(*num)fmt.Println(*isProcess)
}

运行结果:

wohu@wohu:~/GoCode/src/task$ go run main.go --mode "hello" --num 10 --isProcess=0
Before Parse registerNum is 0
After Parse registerNum is 3
flagArgs is []string{}
hello
10
false
wohu@wohu:~/GoCode/src/task$ ^C

3.2 解析 flag 参数为变量

package mainimport ("flag""fmt"
)func main() {// 定义命令行参数var mode stringvar num intvar isProcess bool// flag.StringVar这样的函数第一个参数换成了变量地址,后面的参数和flag.String是一样的flag.StringVar(&mode, "mode", "", "process mode")flag.IntVar(&num, "num", 5, "process number")flag.BoolVar(&isProcess, "isProcess", true, "process bool")// 解析命令行参数flag.Parse()// 输出命令行参数fmt.Println("mode is ", mode)fmt.Println("num is ", num)fmt.Println("isProcess is ", isProcess)
}

flag.StringVarflag.String 的区别:

  1. flag.StringVar 函数第一个参数为变量地址,该变量需要提前声明,其余参数和 flag.String 是一样的;
  2. flag.StringVar 第一个参数就是变量的实际值,可以直接使用,而 flag.String 返回的是一个指针地址,使用的时候需要加 * 标记;

其它 flag.xxxflag.xxxVar 的区别和上面所说的一样。

3.3 自定义 flag 参数

使用 flag.var() 可以把自定义的数据类型作为参数值的类型,核心在于自定义的数据类型需要实现Value接口。

package mainimport ("errors""flag""fmt""strconv""strings"
)type Student struct {Name stringAge  int
}func (s *Student) String() string {return fmt.Sprintf("Name: %s, Age: %d\n", s.Name, s.Age)
}func (s *Student) Set(_s string) error {studentArr := strings.Split(_s, ",")if len(studentArr) == 2 {s.Name = studentArr[0]s.Age, _ = strconv.Atoi(studentArr[1])return nil}return errors.New("error")
}func main() {name := flag.String("name", "admin", "user name")s := new(Student)flag.Var(s, "student", "student info")flag.Parse()fmt.Println("hello,", *name)fmt.Println(s)
}

执行结果:

wohu@wohu:~/GoCode/src$ go run demo.go -name "wohu" -student "wohu",20
hello, wohu
Name: wohu, Age: 20wohu@wohu:~/GoCode/src$

Go 学习笔记(45)— Go 标准库之 flag(命令行参数解析)相关推荐

  1. GO标准库—命令行参数解析FLAG

    评论有人提到没有例子,不知道讲的是什么.因此,为了大家能够更好地理解,特意加了一个示例.其实本文更多讲解的是 flag 的实现原理,加上示例之后,就更好地知道怎么使用了.建议阅读 <Go语言标准 ...

  2. Python学习笔记: Python 标准库概览

    本文来自:入门指南 开胃菜参考:开胃菜 使用Python解释器:使用Python解释器 本文对Python的简介:Python 简介 Python流程介绍:深入Python 流程 Python数据结构 ...

  3. boost学习之命令行参数解析库program_options

    介绍 程序参数项(program options)是一系列name=value对,program_options 允许程序开发者获得通过命令行(command line)和配置文件(config fi ...

  4. python基础教程_学习笔记14:标准库:一些最爱——re

    标准库:一些最爱 re re模块包括对正則表達式的支持,由于以前系统学习过正則表達式,所以基础内容略过,直接看python对于正則表達式的支持. 正則表達式的学习,见<Mastering Reg ...

  5. python基础课程_学习笔记13:标准库:有些收藏夹——sys

    标准库:有些收藏夹 sys sys这个模块可以让你访问和python解释器联系紧密的变量和函数. sys模块中一些重要的函数和变量 函数/变量 描写叙述 argv 命令行參数,包含脚本名称 exit( ...

  6. Python学习笔记: Python 标准库概览二

    本文来自:入门指南 开胃菜参考:开胃菜 使用Python解释器:使用Python解释器 本文对Python的简介:Python 简介 Python流程介绍:深入Python 流程 Python数据结构 ...

  7. 命令行参数tail c语言,osg学习笔记2, 命令行参数解析器ArgumentParser

    php简单实现socket通信 socket通信的原理在这里就不说了,它的用途还是比较广泛的,我们可以使用socket来做一个API接口出来,也可以使用socket来实现两个程序之间的通信,我们来研究 ...

  8. Python学习笔记17:标准库之数学相关(math包,random包)

    前面几节看得真心累.如今先来点简单easy理解的内容. 一 math包 math包主要处理数学相关的运算. 常数 math.e   # 自然常数e math.pi  # 圆周率pi 运算函数 math ...

  9. Python学习笔记14:标准库之信号量(signal包)

    signal包负责在Python程序内部处理信号.典型的操作包含预设信号处理函数,暂停并等待信号,以及定时发出SIGALRM等. 要注意,signal包主要是针对UNIX平台(比方Linux, MAC ...

最新文章

  1. 初识Service Worker
  2. python制作贪吃蛇游戏_用Python写贪吃蛇游戏的代码实例
  3. 【Android 异步操作】FutureTask 分析 ( Future 接口解析 | Runnable 接口解析 | Callable 接口解析 )
  4. Python小白学习之函数装饰器
  5. 【音频处理】离散傅里叶变换
  6. 一步一步学Remoting系列文章
  7. Python 数据分析三剑客之 NumPy(四):字符串函数总结与对比
  8. VIO Estimator::processIMU 函数
  9. oracle 触发器 insert 前检查_一文看懂INSTEAD OF 与AFTER 触发器区别与联系
  10. 06_LR和最大熵模型_统计学习方法
  11. Kotlin — 心印(熟悉与锻炼Kotlin语法)
  12. 【详细】遍历Windows文件
  13. 1. jQuery 简介
  14. Remoting PerfMon Service
  15. 一个关于Booth算法的文章
  16. 为什么计算机软件比一般作品较多,插画-从入门到进阶的小心得
  17. 应届生产品助理/经理面试,应当多谈点什么?
  18. canvas漫天闪烁的星星
  19. 传输预编码matlab,基于MATLAB的MIMO系统预编码性能仿真.doc
  20. 2017最新qq第三方登陆教程

热门文章

  1. jenkins+sonarqube流水线脚本模板
  2. c/c++中的const
  3. Eclipse+Maven创建web项目
  4. Tensorflow函数——tf.variable_scope()
  5. Druid数据库连接池使用参考
  6. 自动生成低精度深度学习算子
  7. YOLO、SSD、FPN、Mask-RCNN检测模型对比
  8. Cocos 全局变量的使用
  9. python 把字母转数字
  10. RxJava debounce()和throttleWithTimeout()