当前位置: 首页 > 工具软件 > Go Getopt > 使用案例 >

golang 命令行参数解析

方坚壁
2023-12-01

1. golang 命令行参数解析

golang 的命令行参数解析, 推荐两种。一个是 os.Args, 另一个是使用 flag 模块。

1.1. os.Args

package main

import (
	"fmt"
	"os"
)

func main() {
	args := os.Args

	// 使用 go run xx.go 1 2 3 xx aaa bbb ccc  ddd  eee
	// 那么 args 就是 [xx.exe 1 2 3 xx aaa bbb ccc ddd eee]
	// 并且全部是 string 类型
	fmt.Println(args)
}

效果:

$ ./out 1 2 3 xx aaa bbb ccc  ddd  eee
[./out 1 2 3 xx aaa bbb ccc ddd eee]

1.2. flag

flag 模块可以支持使用关键字的方式指定参数。

package main

import (
	"flag"
	"fmt"
)

func main() {
	//flag.Type 里面接受三个参数, 指定的名字, 默认值, 描述信息
	Name := flag.String("name", "mashiro", "姓名")
	Age := flag.Int("age", 16, "年龄")
	has_gf := flag.Bool("has_gf", false, "有女朋友? ")

	//解析
	flag.Parse()

	/*
	我们在命令行中便可以通过 name satori age 16 has_gf false 这种方式指定
	当然还可以使用其他方式比如 --name satori, -name satori, --name=satori,-name=satori
	 */

	//但是注意: 得到的 Name、Age、has_gf 都是指针
	fmt.Println(*Name, *Age, *has_gf)
}

效果:

$ ./out --name koishi -age=15 has_gf false
koishi 15 false

$ ./out -h
Usage of ./out:
  -age int
    	年龄 (default 16)
  -has_gf
    	有女朋友? 
  -name string
    	姓名 (default "mashiro")

1.2.1. flag 的其他参数

package main

import (
	"flag"
	"fmt"
)

func main() {
	Name := flag.String("name", "mashiro", "姓名")
	Age := flag.Int("age", 16, "年龄")
	has_gf := flag.Bool("has_gf", false, "有女朋友? ")
	flag.Parse()

	fmt.Println(*Name, *Age, *has_gf)
	//命令行后的其他参数, 是一个 []string 类型
	fmt.Println(flag.Args())
	//命令行后的其他参数个数
	fmt.Println(flag.NArg())
	//命令行使用的参数个数
	fmt.Println(flag.NFlag())
}

效果:

$ ./out --name koishi -age=15 a b c 1
koishi 15 false
[a b c 1]
4
2

我们后面多指定了 a b c 1, 所以可以通过 flag.Args 来获取, flag.NArgs 就是多指定的参数个数, flag.NFlag 则是我们在命令行, 通过指定关键字的方式指定的参数个数, 这里是 2, 因为 has_gf 我们没有指定, 但即便如此也是打印了默认值的。

flag 模块还可以使用一种方式, flag.TypeVar, 这和 flag.Type 是基本类似的。

package main

import (
	"flag"
	"fmt"
)

func main() {
	var Name string
	var Age int 
	var has_gf bool 
	flag.StringVar(&Name, "name", "mashiro", "姓名")
	flag.IntVar(&Age, "age", 16, "年龄")
	flag.BoolVar(&has_gf, "has_gf", false, "有女朋友? ")
	flag.Parse()

	fmt.Println(Name, Age, has_gf)
	fmt.Println(flag.Args())
	fmt.Println(flag.NArg())
	fmt.Println(flag.NFlag())
}

flag.Type 是直接返回一个指针, flag.TypeVar 则是需要先声明变量, 然后把指针传进去, 至于后面的参数、以及结果都是一样的。

1.2.2. 其它

1.2.2.1. 命令行解析出来后对应的是代码中的变量, 在 flag 包中获取的变量支持的类型有:

    1. bool
    1. time.Duration
    1. float64
    1. int
    1. int64
    1. string
    1. uint
    1. uint64

1.2.2.2. 将命令行输入值赋值到对应变量的方法:

  • 1)bool 类型对应:
Bool(name string, value bool, usage string) *bool
         BoolVar(p *bool, name string, value bool, usage string)
  • 2)time.Duration 类型对应:
Duration(name string, value time.Duration, usage string) *time.Duration
         DurationVar(p *time.Duration, name string, value time.Duration, usage string)
  • 3)float64 类型对应:
Float64(name string, value float64, usage string) *float64
Float64Var(p *float64, name string, value float64, usage string)
  • 4)int 类型对应:
Int(name string, value int, usage string) *int
IntVar(p *int, name string, value int, usage string)
  • 5)int64 类型对应:
Int64(name string, value int64, usage string) *int64
Int64Var(p *int64, name string, value int64, usage string)
  • 6)string 类型对应:
String(name string, value string, usage string) *string
StringVar(p *string, name string, value string, usage string)
  • 7)uint 类型对应:
Uint(name string, value uint, usage string) *uint
UintVar(p *uint, name string, value uint, usage string)
  • 8)uint64 类型对应:
Uint64(name string, value uint64, usage string) *uint64
Uint64Var(p *uint64, name string, value uint64, usage string)

1.2.2.3. 默认值和用法说明:

获取命令行参数接口中 value 参数为默认值, usage 参数为命令行使用说明。用 programname + -h 可以看到 usage 对应的字符串。

下面以一个例子来看看 flag 的使用方法:

func main() {
	var lang = flag.String("lang", "golang", "the lang of the program")
	var age = flag.Int64("age", 18, "the age of the user")
	var safemod = flag.Bool("safemod", true, "whether using safemode")
	flag.Parse()

	fmt.Println("lang is: ", *lang)
	fmt.Println("age is: ", *age)
	fmt.Println("safemod is: ", *safemod)
}

直接运行结果如下:

lang is:  golang
age is:  18
safemod is:  true

-h 显示如下:

Usage of test.exe:
  -age int
        the age of the user (default 18)
  -lang string
        the lang of the program (default "golang")
  -safemod
        whether using safemode (default true)

从例子可以看出, 绑定好变量后, 直接调用 flag.Parse() 方法, 就可以解析出命令行参数了。这个比 C++ 中的 getopt 来的简单直观很多。

 类似资料: