Golang学习实战笔记-基础 > golang底层实现原理
golang 自带读取命令行工具 flag使用

使用flag主要包括以下几步


定义flag参数,有三种方式

通过flag.String(), Bool(), Int() 等flag.Xxx()方法,该种方式返回一个相应的指针

import "flag"
...
ip := flag.string("flagname", "默认值", "参数说明")

通过flag.XxxVar()方法将flag绑定到一个变量,该种方式返回值类型,如

var flagvar intfunc init() {
    flag.IntVar(&flagvar, "flagname", 1234, "help message for flagname")
}

通过flag.Var()绑定自定义类型,自定义类型需要实现Value接口(Receives必须为指针),如

flag.Var(&flagVal, "name", "help message for flagname")

对于这种类型的flag,默认值为该变量类型的初始值


调用flag.Parse()解析命令行参数到定义的flag

flag.Parse()

解析函数将会在碰到第一个非flag命令行参数时停止,非flag命令行参数是指不满足命令行语法的参数,如命令行参数为cmd --flag=true abc则第一个非flag命令行参数为“abc”


调用Parse解析后,就可以直接使用flag本身(指针类型)或者绑定的变量了(值类型)

fmt.Println("ip has value ", *ip)
fmt.Println("flagvar has value ", flagvar)

还可通过flag.Args(), flag.Arg(i)来获取非flag命令行参数


示例

示例1: 获取“species” flag的值,默认为“gopher”

var species = flag.String("species", "gopher", "the species we are studying")

示例2: 两个flag共享同一个变量,一般用于同时实现完整flag参数和对应简化版flag参数,需要注意初始化顺序和默认值

    

var gopherType stringfunc init() {
  const (
    defaultGopher = "pocket"
    usage       = "the variety of gopher"
  )
  flag.StringVar(&gopherType, "gopher_type", defaultGopher, usage)
  flag.StringVar(&gopherType, "g", defaultGopher, usage+"(shorthand)")
}

示例3: 将flag绑定用户自定义类型。按我们先前所说,只需要实现Value接口,但实际上,如果需要取值的话,需要实现Getter接口,看下接口定义就明白了:


type Getter interface {
  Value
  Get(string) interface{}
}
type Value interface {
  String() string
  Set(string) error
}
接下来,我们实现一个解析并格式化命令行输入的时间集合的例子,如下
package main
import (
  "errors"
  "flag"
  "fmt"
  "strings"
  "time"
)
type interval []time.Duration
//实现String接口
func (i *interval) String() string {
  return fmt.Sprintf("%v", *i)
}
//实现Set接口,Set接口决定了如何解析flag的值
func (i *interval) Set(value string) error {
    //此处决定命令行是否可以设置多次-deltaT
  if len(*i) > 0 {
    return errors.New("interval flag already set")
  }
  for _, dt := range strings.Split(value, ",") {
    duration, err := time.ParseDuration(dt)
    if err != nil {
      return err
    }
    *i = append(*i, duration)
  }
  return nil
}
var intervalFlag interval
func init() {
  flag.Var(&intervalFlag, "deltaT", "comma-separated list of intervals to use between events")
}
func main() {
  flag.Parse()
  fmt.Println(intervalFlag)
}

运行结果:

//./commandLine -deltaT 61m,72h,80s[1h1m0s 72h0m0s 1m20s]