在 golang 的 flag 中自定义参数类型

发布于 2022-11-04 11:24:36 字数 2002 浏览 178 评论 0

Golang 的 flag 包能够帮助我们轻松实现一个命令行程序的参数解析,如:

package main

import (
   "flag"
   "fmt"
)

func main() {
   debug := flag.Bool("verbose", false, "Verbose log output.")
   name := flag.String("name", "", "your Name")
   
   flag.Parse()
   fmt.Println(*debug)
   fmt.Println(*name)
}

这个时候运行就可以看到我们命令行的参数:

Flag 是不区分短选项和长选项的(即不区分 flag、option、arguments 这些概念 https://unix.stackexchange.com/questions/285575/whats-the-difference-between-a-flag-an-option-and-an-argument)

Flag 只支持简单的参数类型(bool、int、string),如果要使用复杂一些的类型,就需要自己去实现 Value 接口:

type Value interface {
   String() string
   Set(string) error
}

其中String方法格式化该类型的值,flag.Parse方法在执行时遇到自定义类型的选项会将选项值作为参数调用该类型变量的Set方法。

如最长被使用到的slice类型可以这么定义:

type arrayFlags []string

func (i *arrayFlags) String() string {
   return strings.Join(*i,", ")
}
func (i *arrayFlags) Set(value string) error {
   *i = append(*i, value)
   return nil
}

使用的时候使用 flag.Var

var exclusionGlobs arrayFlags

flag.Var(&exclusionGlobs, "exclude", "Glob of files that should not be pruned. Can be specified multiple times.")

在命令行中多次指定这个option就可以了,如

cli --exclude arg1 --exclude arg2

再比如使用 map 类型可以类似这样定义:

func (f mapFlag) String() string {
        return fmt.Sprintf("%v", map[string]string(f))
}

func (f mapFlag) Set(value string) error {
        split := strings.SplitN(value, "=", 2)
        f[split[0]] = split[1]
        return nil
}

func main() {
    var hostsFlag sliceFlag
    flag.Var(&hostsFlag, "env", "env list,for example: -env key1=value1 -env key2=value2")
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

虚拟世界

暂无简介

0 文章
0 评论
23 人气
更多

推荐作者

qq_Yqvrrd

文章 0 评论 0

2503248646

文章 0 评论 0

浮生未歇

文章 0 评论 0

养猫人

文章 0 评论 0

第七度阳光i

文章 0 评论 0

新雨望断虹

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文