将pflags.Flag.Value强制转换为任意类型

huangapple go评论78阅读模式
英文:

Casting pflags.Flag.Value as Arbitrary Types

问题

我正在使用github.com/spf13/cobra来解析命令行标志,几乎所有的工作都进行得很顺利,但是我在运行时遇到了一个问题,即如何从*cobra.Command中获取特定类型的值。

我的命令定义在cmd/generate.go中,如下所示:

var (
    generateCommand = &cobra.Command{
        // ...
    }

    generateTokenCommand = &cobra.Command{
        // ...
        Run: func(cmd *cobra.Command, args []string) {
           // command body here
        }
    }

)

func init() {
    generateCommand.AddCommand(generateTokenCommand)

    // 设置生成令牌的标志
    flags := generateTokenCommand.Flags()
    flags.Uint64P("user-id", "i", 1, "User ID")
    flags.BoolP("is-admin", "a", false, "Is admin.")
    // 其他的flags.StringP,但那些很容易
}

注意:我知道有一些API可以将它们绑定到静态变量,但如果可能的话,我想避免这样做,以保持在Cobra内部。

generateTokenCommand.Run中,也就是我的入口点,我在从cobra.Command中获取非字符串值时遇到了问题。

当我需要获取一个字符串值时,我可以简单地使用以下代码:

var email string = cmd.Flag("email").Value.String()

pflags.Flag有一个名为Value的字段,它的类型是pflags.Value,如下所示:

// Value是存储在标志中的动态值的接口。
// (默认值表示为字符串。)
type Value interface {
	String() string
	Set(string) error
	Type() string
}

如果我进入调试器并像这样获取值:

userIdValue := cmd.Flag("user-id").Value

我发现这个值的运行时类型是*github.com/spf13/pflag.uint64Value,但由于这是一个私有类型,我似乎无法将该值转换为uint64

// 无法编译通过
cmd.Flag("user-id").Value.(uint64)

我该如何将这个Value转换为uint64或使用其他方法来解析它呢?

英文:

I am using github.com/spf13/cobra to parse command-line flags and just about everything I'm doing is working well, but I'm having trouble figuring out how to get a specifically typed value out of a *cobra.Command at runtime.

My command definition looks like this in cmd/generate.go:

var (
    generateCommand = &cobra.Command{
        // ...
    }

    generateTokenCommand = &cobra.Command{
        // ...
        Run: func(cmd *cobra.Command, args []string) {
           // command body here
        }
    }

)

func init() {
    generateCommand.AddCommand(generateTokenCommand)

    // setup generate token flags
    flags := generateTokenCommand.Flags()
    flags.Uint64P("user-id", "i", 1, "User ID")
    flags.BoolP("is-admin", "a", "Is admin.")
    // other flags.StringP, but those are easy
}

> NOTE: I know that there are APIs for binding these to static variables, I'm trying to avoid doing that if at all possible to keep things contained within Cobra.

Inside generateTokenCommand.Run, e.g. my entry point, I'm having trouble getting non-string values out of cobra.Command.

When I need to get a string value, I can simply:

var email string = cmd.Flag("email").Value.String()

pflags.Flag has a field named Value, which is of type pflags.Value, which looks like this:

// Value is the interface to the dynamic value stored in a flag.
// (The default value is represented as a string.)
type Value interface {
	String() string
	Set(string) error
	Type() string
}

If I drop into a debugger and grab the value like so:

userIdValue := cmd.Flag("user-id").Value

I see that the runtime type of this is *github.com/spf13/pflag.uint64Value, but since this is a private type, I don't seem to be able to cast the value:

// does not compile
cmd.Flag("user-id").Value.(uint64)

How can I cast or use another method to resolve this Value as a uint64?

答案1

得分: 1

我在深入研究后可能找到了答案,pflags.FlagSet 上有一个名为 GetUint64 的方法:

// GetUint64 return the uint64 value of a flag with the given name
func (f *FlagSet) GetUint64(name string) (uint64, error) {
    val, err := f.getFlagType(name, "uint64", uint64Conv)
    if err != nil {
        return 0, err
    }
    return val.(uint64), nil
}

我认为我的问题是对文档和 Golang 源代码组织方式的适应,但这确实有效:

uid, err := cmd.Flags().GetUint64("user-id")
英文:

I may have found the answer after diving deeper, there is a method on pflags.FlagSet called GetUint64:

// GetUint64 return the uint64 value of a flag with the given name
func (f *FlagSet) GetUint64(name string) (uint64, error) {
	val, err := f.getFlagType(name, "uint64", uint64Conv)
	if err != nil {
		return 0, err
	}
	return val.(uint64), nil
}

I think my issue has been getting used to the documentation and the way that Golang source code is organized, but this does work:

uid, err := cmd.Flags().GetUint64("user-id")

huangapple
  • 本文由 发表于 2021年8月13日 11:58:03
  • 转载请务必保留本文链接:https://go.coder-hub.com/68766579.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定