我是眼镜蛇和毒蛇的新手。
我想知道是否有一种方法可以从cli中排除非用户设置的标志值。所以我的问题是,我的cobracmd
中有一些具有默认值的可选标志。我想知道如果这些可选标志不是由用户设置的,是否有办法将其排除在处理之外?或者从另一个角度来看,是否有一种方法可以从cmd
标志集中提取用户从cli中明确更改的标志?
这里有一个例子来更好地说明我的情况:
var cmd = &cobra.Command{
Use: "command [operations]",
Short: "Perform some commands",
Run: func(cmd *cobra.Command, args []string) {
var user User
err := viper.Unmarshal(&user)
fmt.Println(err)
fmt.Println(user)
},
}
cmd.PersistentFlags().String("name", "", "Your Name (Required)")
cmd.PersistentFlags().String("description", "", "Description")
cmd.PersistentFlags().String("address", "", "Address")
cmd.PersistentFlags().Int("age", -1, "Age")
cmd.MarkPersistentFlagRequired("name")
viper.BindPFlags(cmd.PersistentFlags())
所以假设对于年龄和地址,我希望它们是可选的,并且在传递给struct时不进行传播。因此,这意味着,在cli中,用户不需要提交age
和address
标志,这些可选标志的默认值为零。然而,Int&字符串标志是强类型的,因此它们需要默认值(例如:""
和-1
)。因此,当我将命令pflags绑定到viper并且用户不输入年龄时;cli中的地址值,viper将收到地址""
和年龄-1
。使用上面的方法,默认值将被传播到User结构。
我想要的是排除不是由用户设置的标志值。有没有一种方法可以将User结构从接收未由用户显式设置的标志值中排除?
我目前的解决方案是将未设置的标志排除在用户结构中进行处理,目前是这样的:
- 有一个命令标志数组。初始化空
map[string]interface{}
- 遍历数组,并检查是否通过
flags.Changed("flag")
设置/更改了标志。若标志已更改,则将其添加到地图中 - 将映射转换为json
将json对象分解为结构
// inside the Run function of a cobra command aMap := make(map[string]interface{}) flags := cmd.Flags() for _, flag := range cmdFlags { if flags.Changed(flag) { aMap[flag] = viper.Get(flag) } } jsonStr, _ := json.Marshal(aMap) var user User json.Unmarshal(jsonStr, &user) fmt.Println(user)
但我想知道是否有比我上面的解决方案更好的替代方案。最好,我不想更改User
结构中的任何内容,因为它是从外部包导入的。
谢谢。非常感谢你的帮助。
假设您的User
结构如下所示:
type User struct {
...
age int
address string
...
}
则默认情况下,User
结构体的初始化将设置age => 0, address => 0
。所以即使viper没有设置默认值。内部去吧。
我的建议是:
1。更改创建用户结构的方式
type User struct {
...
age *int
address *string
...
}
- 将cobra中这两个字段的默认值设置为
nil
这样你就会知道Cobra的默认值是不设置值。无论何时设置该值,它都将是非nil
值。希望能有所帮助