ZetCode

Go 标志

最后修改时间 2024 年 4 月 11 日

在本文中,我们将展示如何使用 flag 包在 Golang 中解析命令行参数。

flag 包实现了命令行标志解析。命令行参数可在 os.Args 切片中找到。flag 包允许对其进行更灵活的处理。

此外,还有一些第三方包,例如 Cobra,提供了更多附加功能。

func String(name string, value string, usage string) *string
func StringVar(p *string, name string, value string, usage string)

flag 包包含多个用于解析不同类型标志的函数。每种标志类型都有两种选择。区别在于第一个返回指向变量的指针,而另一个接受指向变量的指针。

使用 flag.Args,我们可以解析非标志参数;这些参数必须跟在标志参数后面。

Go 标志语法

编写标志有几种方式。

-count=x
-count x
--count=x
--count x

这些是除布尔值以外所有类型的选项。

-upper
--upper
-upper=value
--upper=value

布尔标志有以下选项。

Go 标志简单示例

下面的示例是一个简单的程序,它解析一个整数参数。

simple.go
package main

import (
    "flag"
    "fmt"
)

func main() {
    num := flag.Int("n", 5, "# of iterations")
    flag.Parse()

    n := *num
    i := 0

    for i < n {
        fmt.Println("falcon")
        i++
    }
}

该程序将单词“falcon”打印 n 次;n 值从命令行参数解析。

import (
    "flag"
    "fmt"
)

首先,我们导入 flag 包。

num := flag.Int("n", 5, "# of iterations")

我们使用 flag.Int 注册一个 int 标志。第一个参数是标志的名称,第二个是默认值,第三个是标志的描述。

flag.Parse()

我们使用 flag.Parse 处理标志。

n := *num

由于我们使用了返回指向变量的指针的函数,因此我们解引用指针并获取值。

for i < n {
    fmt.Println("falcon")
    i++
}

我们将单词“falcon”打印 n 次。

$ go run simple.go 
falcon
falcon
falcon
falcon
falcon
$ go run simple.go -n 3
falcon
falcon
falcon

Go flag.String & flag.Int

flag.String 使用指定的名称、默认值和用法字符串定义一个字符串标志。返回值是存储标志值的字符串变量的地址。flag.Int 使用指定的名称、默认值和用法字符串定义一个 int 标志。返回值是存储标志值的 int 变量的地址。

string_int.go
package main

import (
    "flag"
    "fmt"
)

var (
    env  *string
    port *int
)

func init() {
    env = flag.String("env", "development", "current environment")
    port = flag.Int("port", 3000, "port number")
}

func main() {

    flag.Parse()

    fmt.Println("env:", *env)
    fmt.Println("port:", *port)
}

该程序使用两个标志:环境选项和端口号。

func init() {
    env = flag.String("env", "development", "current environment")
    port = flag.Int("port", 3000, "port number")
}

我们可以将我们的语句放在 init 函数中,该函数通常用于初始化状态变量。

$ go run string_int.go 
env: development
port: 3000
$ go run string_int.go -port 8080
env: development
port: 8080

Go flag.StringVar

flag.StringVar 使用指定的名称、默认值和用法字符串定义一个字符串标志。第一个参数指向一个字符串变量,标志的值将存储在该变量中。

stringvar.go
package main

import (
    "flag"
    "fmt"
)

func main() {

    var name string
    flag.StringVar(&name, "name", "guest", "your name")
    flag.Parse()

    fmt.Printf("Hello %s\n", name)
}

该示例从命令行获取用户的名字。

$ go run stringvar.go 
Hello guest
$ go run stringvar.go -name Peter
Hello Peter

Go flag.PrintDefaults

flag.PrintDefaults 打印集合中所有已定义命令行标志的默认值。

defaults.go
package main

import (
    "flag"
    "fmt"
    "os"
)

func main() {

    var name string
    flag.StringVar(&name, "name", "", "your name")
    flag.Parse()

    if len(name) == 0 {
        fmt.Println("Usage: defaults.go -name")
        flag.PrintDefaults()
        os.Exit(1)
    }

    fmt.Printf("Hello %s\n", name)
}

该程序注册了 name 标志并使其成为必需的。

if len(name) == 0 {
    fmt.Println("Usage: defaults.go -name")
    flag.PrintDefaults()
    os.Exit(1)
}

如果 name 变量为空,我们将打印程序的用法。

$ go run defaults.go 
Usage: defaults.go -name
    -name string
        your name
exit status 1

Go flag.BoolVar

flag.BoolVar 使用指定的名称、默认值和用法字符串定义一个 bool 标志。第一个参数指向一个 bool 变量,标志的值将存储在该变量中。

boolean.go
package main

import (
    "flag"
    "fmt"
    "strings"
)

func main() {

    var name string
    var upper bool

    flag.StringVar(&name, "name", "guest", "your name")
    flag.BoolVar(&upper, "u", false, "display in uppercase")
    flag.Parse()

    var msg string

    msg = fmt.Sprintf("Hello %s", name)

    if upper {
        fmt.Println(strings.ToUpper(msg))

    } else {

        fmt.Println(msg)
    }
}

该程序获取用户的名字和一个布尔标志,用于确定是否将消息写入大写。

$ go run boolean.go -name Peter
Hello Peter
$ go run boolean.go -name Peter -u
HELLO PETER

Go flag.Args

标志后面的参数可作为切片 flag.Args 或单独作为 flag.Arg(i) 访问。参数的索引从 0 到 flag.NArg() - 1

nonflags.go
package main

import (
    "flag"
    "fmt"
    "os"
    "strings"
)

func main() {

    var u bool
    flag.BoolVar(&u, "u", false, "display in uppercase")
    flag.Parse()

    values := flag.Args()

    if len(values) == 0 {
        fmt.Println("Usage: nonflags.go [-u] words ...")
        flag.PrintDefaults()
        os.Exit(1)
    }

    for _, word := range values {

        if u {

            fmt.Println(strings.ToUpper(word))
        } else {

            fmt.Println(word)
        }
    }
}

该程序有一个 u 标志,用于将标志后的所有单词打印为大写。

flag.BoolVar(&u, "u", false, "display in uppercase")

我们定义了布尔标志。

values := flag.Args()

我们从终端获取所有单词。

for _, word := range values {

    if u {

        fmt.Println(strings.ToUpper(word))
    } else {

        fmt.Println(word)
    }
}

我们遍历切片并打印单词;如果设置了 uppercase 标志,则单词将以大写形式打印。

$ go run nonflags.go sky blue falcon cup ocean
sky
blue
falcon
cup
ocean
$ go run nonflags.go -u sky blue falcon cup ocean
SKY
BLUE
FALCON
CUP
OCEAN

来源

Go flag 包 - 参考

在本文中,我们使用 flag 包在 Golang 中解析了命令行参数。

作者

我叫 Jan Bodnar,是一位充满激情的程序员,拥有丰富的编程经验。我自 2007 年以来一直在撰写编程文章。迄今为止,我已撰写了 1,400 多篇文章和 8 本电子书。我在教学编程方面拥有十多年的经验。

列出所有 Go 教程