golang扩展标准flag包参数类型的插件库flagvar的使用

Golang扩展标准flag包参数类型的插件库flagvar的使用

简介

flagvar是一个为Go标准库flag包提供扩展参数类型的插件库,它包含了一系列常用的CLI参数类型。

示例

下面是一个完整的使用示例:

package main

import (
	"flag"
	"fmt"
	"github.com/sgreben/flagvar"
)

var (
	fruit    = flagvar.Enum{Choices: []string{"apple", "banana"}}  // 枚举类型,只能选择apple或banana
	urls     flagvar.URLs                                          // URL列表类型
	settings flagvar.Assignments                                   // 键值对设置类型
)

func main() {
	// 注册flag参数
	flag.Var(&fruit, "fruit", fmt.Sprintf("set a fruit (%s)", fruit.Help()))
	flag.Var(&urls, "url", "add a URL")
	flag.Var(&settings, "set", fmt.Sprintf("specify a setting (%s)", settings.Help()))
	
	// 解析命令行参数
	flag.Parse()
	
	// 使用解析后的参数
	fmt.Println("Selected fruit:", fruit.Value)
	fmt.Println("URLs:", urls.Values)
	fmt.Println("Settings:", settings.Values)
}

使用说明

  1. 枚举类型(Enum):

    • 限制输入值必须在指定范围内
    • 示例: -fruit apple (有效) 或 -fruit kiwi (无效)
  2. URL类型(URLs):

    • 验证输入是否为有效URL
    • 示例: -url https://github.com (有效) 或 -url ://github.com (无效)
  3. 键值对类型(Assignments):

    • 接受KEY=VALUE格式的输入
    • 示例: -set abc=xyz

运行示例

$ go run main.go -set abc=xyz -url https://github.com
# 无错误输出

$ go run main.go -set abc=xyz -url ://github.com
invalid value "://github.com" for flag -url: parse ://github.com: missing protocol scheme

$ go run main.go -fruit kiwi
invalid value "kiwi" for flag -fruit: "kiwi" must be one of [apple banana]

$ go run main.go -h
Usage:
  -fruit value
        set a fruit (one of [apple banana])
  -set value
        specify a setting (a key/value pair KEY=VALUE)
  -url value
        add a URL

类型约定

  1. 复数形式的参数类型(如Strings, Assignments)可以重复指定,值会被收集到切片中
  2. 结果值存储在:
    • 单数类型: .Value字段
    • 复数类型: .Values字段
  3. 原始参数字符串存储在:
    • 单数类型: .Text字段
    • 复数类型: .Texts字段
  4. Set类型(EnumSet, StringSet)会自动去重
  5. CSV类型(IntsCSV, EnumsCSV)接受逗号分隔的值,如果.Accumulate字段设为true,会在多个flag实例间累积值
  6. 大多数类型实现了Help() string接口,可用于生成帮助信息

支持的类型

flagvar提供了多种参数类型,包括但不限于:

  • Enum/Enums: 枚举值
  • URL/URLs: URL地址
  • Assignment/Assignments: 键值对
  • Ints/IntsCSV: 整数值
  • Floats/FloatsCSV: 浮点数值
  • IP/IPs: IP地址
  • Regexp/Regexps: 正则表达式
  • JSON/JSONs: JSON数据
  • Time/Times: 时间值

设计原则

  1. 避免依赖

    • 自包含优于DRY原则
    • 明确支持复制粘贴工作流
    • 匿名结构体优于共享类型
  2. 提供"自己编写代码"的感觉

    • 没有私有字段/方法
    • 没有魔法
    • 尽可能使用简单的内置类型
    • 避免引入新概念
  3. 支持"盲目"使用

    • 零值应该有用
    • 避免引入失败情况,优雅处理任何参数组合
    • 所有"明显应该尝试的事情"都应该有效

更多关于golang扩展标准flag包参数类型的插件库flagvar的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang扩展标准flag包参数类型的插件库flagvar的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


flagvar - 扩展Go标准flag包参数类型的插件库

flagvar是一个用于扩展Go标准库flag包参数类型的插件库,它提供了许多常见类型的flag变量实现,简化了命令行参数处理。

基本使用

首先安装flagvar库:

go get github.com/namsral/flagvar

常用变量类型示例

1. 字符串切片 (StringSlice)

package main

import (
	"flag"
	"fmt"
	"github.com/namsral/flagvar"
)

func main() {
	var files flagvar.StringSlice
	flag.Var(&files, "file", "input files")
	flag.Parse()
	
	fmt.Println("Files:", files)
}

使用方式:

./program -file file1.txt -file file2.txt -file file3.txt

2. 整数范围 (IntRange)

var portRange flagvar.IntRange
flag.Var(&portRange, "port", "port range (min:max)")
flag.Parse()

fmt.Printf("Port range: %d-%d\n", portRange.Min, portRange.Max)

使用方式:

./program -port 8000:9000

3. 枚举值 (Enum)

var logLevel flagvar.Enum
flag.Var(&logLevel, "log-level", "log level", []string{"debug", "info", "warn", "error"})
flag.Parse()

fmt.Println("Log level:", logLevel)

使用方式:

./program -log-level info

4. 正则表达式 (Regexp)

var pattern flagvar.Regexp
flag.Var(&pattern, "pattern", "regex pattern")
flag.Parse()

fmt.Println("Pattern:", pattern.String())

使用方式:

./program -pattern "^[A-Za-z]+$"

5. 时间间隔 (Duration)

var timeout flagvar.Duration
flag.Var(&timeout, "timeout", "operation timeout")
flag.Parse()

fmt.Println("Timeout:", timeout)

使用方式:

./program -timeout 30s

自定义验证器

type PositiveInt int

func (p *PositiveInt) Set(s string) error {
    v, err := strconv.Atoi(s)
    if err != nil {
        return err
    }
    if v <= 0 {
        return fmt.Errorf("must be positive")
    }
    *p = PositiveInt(v)
    return nil
}

func (p *PositiveInt) String() string {
    return strconv.Itoa(int(*p))
}

func main() {
    var count PositiveInt
    flag.Var(&count, "count", "positive integer")
    flag.Parse()
    
    fmt.Println("Count:", count)
}

完整示例

package main

import (
	"flag"
	"fmt"
	"github.com/namsral/flagvar"
)

func main() {
	// 字符串切片
	var files flagvar.StringSlice
	flag.Var(&files, "file", "input files")
	
	// 整数范围
	var ports flagvar.IntRange
	flag.Var(&ports, "ports", "port range (min:max)")
	
	// 枚举值
	var mode flagvar.Enum
	flag.Var(&mode, "mode", "operation mode", []string{"read", "write", "delete"})
	
	// 正则表达式
	var pattern flagvar.Regexp
	flag.Var(&pattern, "pattern", "matching pattern")
	
	// 时间间隔
	var interval flagvar.Duration
	flag.Var(&interval, "interval", "polling interval")
	
	flag.Parse()
	
	fmt.Println("Files:", files)
	fmt.Printf("Ports: %d-%d\n", ports.Min, ports.Max)
	fmt.Println("Mode:", mode)
	fmt.Println("Pattern:", pattern.String())
	fmt.Println("Interval:", interval)
}

使用方式:

./program -file a.txt -file b.txt -ports 8000:9000 -mode write -pattern ".*go$" -interval 5s

优势

  1. 提供丰富的预定义参数类型
  2. 简化复杂参数的处理
  3. 内置参数验证
  4. 与标准flag包完全兼容
  5. 易于扩展自定义类型

flagvar库是标准flag包的完美补充,特别适合需要处理复杂命令行参数的场景。

回到顶部