我最近刚开始与Go合作,我遇到了一些与Cobra和Viper合作的行为,我不确定我是否理解。
这是您通过运行 获得的示例代码的略微修改版本。在我有:cobra initmain.go
package main
import (
"github.com/larsks/example/cmd"
"github.com/spf13/cobra"
)
func main() {
rootCmd := cmd.NewCmdRoot()
cobra.CheckErr(rootCmd.Execute())
}
在我有:cmd/root.go
package cmd
import (
"fmt"
"os"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)
var cfgFile string
func NewCmdRoot() *cobra.Command {
config := viper.New()
var cmd = &cobra.Command{
Use: "example",
Short: "A brief description of your application",
PersistentPreRun: func(cmd *cobra.Command, args []string) {
initConfig(cmd, config)
},
Run: func(cmd *cobra.Command, args []string) {
fmt.Printf("This is a test\n")
},
}
cmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.example.yaml)")
cmd.PersistentFlags().String("name", "", "a name")
// *** If I move this to the top of initConfig
// *** the code runs correctly.
config.BindPFlag("name", cmd.Flags().Lookup("name"))
return cmd
}
func initConfig(cmd *cobra.Command, config *viper.Viper) {
if cfgFile != "" {
// Use config file from the flag.
config.SetConfigFile(cfgFile)
} else {
config.AddConfigPath(".")
config.SetConfigName(".example")
}
}
此代码将在最终调用时出现 nil 指针引用,从而导致恐慌:fmt.Printf
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x50 pc=0x6a90e5]
如果我将调用从函数移动到命令的顶部,则一切都运行没有问题。config.BindPFlagNewCmdRootinitConfig
这是怎么回事?根据蝰蛇关于使用的文档:BindPFlags
与 BindEnv 一样,该值不是在调用绑定方法时设置的,而是在访问绑定方法时设置的。这意味着您可以根据需要尽早绑定,即使在 init() 函数中也是如此。
这几乎就是我在这里所做的。在我调用时,是非 nil,是非 nil,并且参数已被注册。config.BindPflagconfigcmdname
我假设我在 中的闭包中使用了一些东西,但我不知道为什么这会导致这种失败。configPersistentPreRun
神不在的星期二
慕勒3428872
相关分类