Go语言标准库学习flag——很方便的编写自己的命令行程序

Go语言Flag包详解
本文深入解析Go语言中的Flag包,展示如何使用Flag包自定义命令行参数,包括定义、解析参数,以及自定义参数类型和值。文章还介绍了如何重写Usage函数来自定义帮助信息。

和其它语言一样,go语言也提供了用来接收命令行参数的功能(flag包),我们可以使用flag包很方便的写一些自定义的命令,就像cobra包一样,这里向大家介绍flag包的使用方法,如果项目需要复杂或更高级的命令行解析方式,可以使用 https://github.com/urfave/cli 或者 https://github.com/spf13/cobra 这两个强大的库。希望对你有帮助。

一、flag自定义命令的步骤

flag包自定义的步骤很简单,一般只需要两步:

  • 接收参数

  • 解析参数

  • 自定义方法处理命令

下面看个例子:

package main

import (
	"flag"
	"fmt"
)

// 定义OK为bool类型,用来接收传入的参数
var OK bool

func main() {
   
   
    // 下面为获取命令行的参数并将值赋值给OK
    // 1) 参数名称为ok,默认值为false
    // 2) usage为print ok
    // 当使用-ok参数时,OK的值会变为true
	flag.BoolVar(&OK, "ok", false, "print ok")
    // 解析参数
	flag.Parse()
    // 自定义方法处理命令
	if OK {
   
   
		fmt.Println("OK")
	} else {
   
   
		fmt.Println("Not OK")
	}
}

我们来看一下测试结果:

$ go run main.go -ok
OK
$ go run main.go
Not OK

二、使用flag获取命令行参数

1. 使用flag获取命令行参数有两种方式
1.1 flag.Xxx(),其中 Xxx 可以是 Int、String,Bool 等;返回一个相应类型的指针,如:

var config = flag.String("config", "config.cfg", "config file")

这种方式会从命令行读取参数后,并将参数值返回,config会接收返回的值,String方法有三个参数(其他类型也一样):

  • 第一个参数:定义参数名称,命令行可以通过指定config的值来传递数据。
  • 第二个参数:定义参数的默认值,如果命令行没有接收到config的值,则使用默认值。
  • 第三个参数:定义参数的实用信息,也就是help信息。
1.2 flag.XxxVar(),将 flag 绑定到一个变量上,如:
var config string
flag.StringVar(&config, "config", "config.cfg", "config file")

这种方式有四种参数,后面三种和上一种获取flag参数的含义相同,唯一的不同点是,在StringVar中,第一个参数为一个字符串类型的指针(其他类型类似),我们只需要提前定义好变量,并引入变量即可,实现的效果和上面那种方式是一样的。

2. 自定义Value
2.1 flag命令除了可以接收官方提供的参数类型外,我们可以自定义flag,只要实现 flag.Value 接口即可(要求 receiver 是指针),这时候可以通过如下方式定义该 flag:

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

2.2 flag.Value接口
type Value interface {
   
   
	String() string
	Set(string) error
}

flag.Value接口只有两个方法,我们只需要创建一个实例并实现这两个方法即可。

2.3 自定义Value

在flag中对Duration这种非基本类型的支持,就是使用的类似的方式,我们来看一下他是怎么实现的:

(1)首先定义了一个time.Duration类型

// -- time.Duration Value
type durationValue time.Duration

(2)通过newDurationValue函数new一个存放参数值的指针

func newDurationValue(val time.Duration, p *time.Duration) *durationValue {
   
   
	*p = val
	return (*durationValue)(p)
}

(3)实现flag.Getter接口,flag.Getter接口继承了flag,Value接口

func (d *durationValue) Set(s string) error {
   
   
	v, err := time.ParseDuration(s)
	if err != nil {
   
   
		err = errParse
	}
	*d = durationValue(v)
	return err
}

func (d *durationValue) Get() interface{
   
   }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值