我有以下配置模型:type Config struct { Project []Project `mapstructure:"project"`}type Project struct { Name string `mapstructure:"name"`}我希望能够使用配置文件以及命令行上的选项对此进行配置。我知道如何通过以正确的格式传递它然后取消编组来执行配置文件。但是,我无法弄清楚该怎么做的是使用Cobra在命令行上设置项目名称,然后让Viper将该值绑定为Project数组中的第一项。以下是我放在一起的简单程序,以显示我遇到的问题:package mainimport ( "fmt" "log" "github.com/spf13/cobra" "github.com/spf13/viper")type Config struct { Project []Project `mapstructure:"project"` Name string `mapstructure:"name"`}type Project struct { Name string `mapstructure:"name"`}var ( config Config rootCmd = &cobra.Command{ Use: "rjsdummy", Short: "Dummy app to understand Viper BindPFlags", Long: "", PersistentPreRun: preRun, Run: executeRun, })func init() { var name string var project_name string cobra.OnInitialize() // configure the flags on the command line rootCmd.Flags().StringVarP(&name, "name", "n", "", "Your name") rootCmd.Flags().StringVarP(&project_name, "project", "p", "", "Project name") // bind the flags to the configuration viper.BindPFlag("name", rootCmd.Flags().Lookup(("name"))) viper.BindPFlag("project.0.name", rootCmd.Flags().Lookup(("project")))}func preRun(ccmd *cobra.Command, args []string) { err := viper.Unmarshal(&config) if err != nil { log.Fatalf("Unable to read Viper options into configuration: %v", err) }}func executeRun(ccmd *cobra.Command, args []string) { fmt.Printf("Your name: %s\n", config.Name) fmt.Printf("Project name: %s\n", config.Project[0].Name)}func main() { rootCmd.Execute()}当我使用命令运行此命令时,我得到以下输出:go run .\binding.go -n Russell -p Turtle所以我知道这条线不起作用。如果我将其更改为,我将获得堆栈跟踪。问题是我如何添加这个(和其他属性)作为复杂对象数组中的第一项?我可以有第二个Viper来读取另一个对象,然后添加到主配置中,还是有另一种方法?viper.BindPFlag("project.0.name", rootCmd.Flags().Lookup(("project")))project[0].name
1 回答
斯蒂芬大帝
TA贡献1827条经验 获得超8个赞
在玩了这个问题之后,我有了答案。
即使我已经设置了配置,以便它有一个切片项目,Viper也足够聪明地解决了这个问题。Project []Project
因此,要将项目名称绑定到切片的第一个元素,就像使用:
viper.BindPFlag("project.name", runCmd.Flags().Lookup("name"))
不需要索引。但是,我可以打印以下值:
fmt.Println(Config.Project[0].Name)
我过度思考这个
- 1 回答
- 0 关注
- 48 浏览
添加回答
举报
0/150
提交
取消