作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我最近才开始使用 Go,我遇到了一些
我不确定我是否理解与 Cobra 和 Viper 合作的行为。
这是您获得的示例代码的略微修改版本
运行 cobra init
.在 main.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")
}
config.AutomaticEnv() // read in environment variables that match
// If a config file is found, read it in.
if err := config.ReadInConfig(); err == nil {
fmt.Fprintln(os.Stderr, "Using config file:", config.ConfigFileUsed())
}
// *** This line triggers a nil pointer reference.
fmt.Printf("name is %s\n", config.GetString("name"))
}
此代码将在最终调用时出现 nil 指针引用 panic
fmt.Printf
:
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x50 pc=0x6a90e5]
如果我把电话转到
config.BindPFlag
来自
NewCmdRoot
函数到
initConfig
的顶部命令,一切运行
BindPFlags
:
Like BindEnv, the value is not set when the binding method iscalled, but when it is accessed. This means you can bind as early asyou want, even in an init() function.
config.BindPflag
,
config
非零,
cmd
是非零,并且
name
参数已注册。
config
的使用有问题在一个
PersistentPreRun
,但我不知道为什么会这样
最佳答案
我觉得这很有趣,所以我做了一些挖掘和found your exact problem documented in an issue .有问题的行是这样的:
config.BindPFlag("name", cmd.Flags().Lookup("name"))
// ^^^^^^^
您创建了一个永久标志,但将该标志绑定(bind)到
Flags
属性(property)。如果您将代码更改为绑定(bind)到
PersistentFlags
,即使使用
NewCmdRoot
中的这一行,一切都会按预期工作:
config.BindPFlag("name", cmd.PersistentFlags().Lookup("name"))
关于go - 为什么我会根据调用 BindPFlag 的位置收到零指针错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67742457/
我最近才开始使用 Go,我遇到了一些 我不确定我是否理解与 Cobra 和 Viper 合作的行为。 这是您获得的示例代码的略微修改版本 运行 cobra init .在 main.go我有: pac
我是一名优秀的程序员,十分优秀!