gpt4 book ai didi

go - 在 Cobra 命令行工具中,如何为不同的标志使用相同的变量?

转载 作者:行者123 更新时间:2023-12-01 22:15:40 26 4
gpt4 key购买 nike

此示例 Cobra 应用程序,https://github.com/kurtpeek/myCobraApp , 包含一个使用 Cobra 生成器搭建的 Cobra 应用程序,其中包含以下命令:

cobra add serve
cobra add config

目录结构为
.
├── LICENSE
├── cmd
│   ├── config.go
│   ├── root.go
│   └── serve.go
├── go.mod
├── go.sum
└── main.go

config.go , 字符串变量 deviceUUID已定义并绑定(bind)到该命令的标志,默认值为 "configDeviceUUID" :

var deviceUUID string

func init() {
rootCmd.AddCommand(configCmd)

// Cobra supports local flags which will only run when this command
// is called directly, e.g.:
configCmd.Flags().StringVar(&deviceUUID, "deviceUUID", "configDeviceUUID", "Device UUID")
fmt.Println("deviceUUID after config init:", deviceUUID)
}

同样,在 serve.go deviceUUID变量绑定(bind)到本地标志:

func init() {
rootCmd.AddCommand(serveCmd)

serveCmd.Flags().StringVar(&deviceUUID, "deviceUUID", "serveDeviceUUID", "Device UUID")
fmt.Println("deviceUUID after serve init:", deviceUUID)
}

问题是如果我运行 config命令未指定 deviceUUID命令行中的标志,它从 serve 中获取默认值命令:
> go run main.go config
deviceUUID after config init: configDeviceUUID
deviceUUID after serve init: serveDeviceUUID
deviceUUID: serveDeviceUUID
config called

似乎正在发生的是 init()每个文件中的函数按字母顺序运行,最后运行的函数设置标志的默认值。

我怎样才能避免这种行为?我想要 config.go 中设置的默认值始终适用于 config命令。 (当然,我可以声明单独的变量,如 configDeviceUUIDserveDeviceUUID ,但这对我来说似乎有点困惑)。

最佳答案

我不知道你为什么会认为那是乱七八糟的。你有一个变量,你把它设置在几个 init功能,所以最后一个设置是保持设置的那个:你对正在发生的事情的解释是正确的。显然,这实际上是两个不同的变量,只是实际上最多使用其中一个。

(假设还有其他命令可以做其他事情,也许这些全局变量都不会被使用。如果 Go 是一种自然更动态的语言,其中一切都在运行时决定,或者如果您使用的是更动态的运行时设置,你可能还没有创建它们。但这不是 Go:Go 充满了静态类型和静态变量,在链接时创建。)

但是,如果您确实只想使用一个全局变量,显而易见的解决方案是选择一些标记值来表示未设置,并将其设为 Cobra 设置的默认值。然后,如果变量在运行命令时保持“未设置”值,您就知道用户没有提供值。

如果空字符串适合作为这样的哨兵——通常就是这种情况——这很容易。您的每个命令都有几行:

if deviceUUID == "" {
deviceUUID = defaultDeviceUUID
}

你就完成了。

如果 cobra 代码在您这样做时将默认初始化器值保存在某个私有(private)位置,这可能会很好,或者至少对您来说更方便:

configCmd.Flags().StringVar(&deviceUUID, "deviceUUID", "configDeviceUUID", "Device UUID")


然后当顶级命令决定 config 时,将那些私有(private)的、保存的默认值复制到(单个)全局变量中。将使用子命令,而不是将其保存在私有(private)的某个地方,然后将其复制到当时的(单个)全局变量中 configCmd.Flags().StringVar()函数被调用,但这不是它的实际工作方式。所以:
configCmd.Flags().StringVar(&deviceUUID, "deviceUUID", "", "Device UUID")

加上上面的空字符串测试可能就足够了。请注意,每个 init仍然每次都覆盖(单个、共享和可能从未使用过的)全局变量,但所有变量都将其从初始空字符串值设置为新的空字符串值,保持不变。

关于go - 在 Cobra 命令行工具中,如何为不同的标志使用相同的变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60443941/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com