当yaml已经初始化该值时,如何在Golang中测试默认值?

当yaml已经初始化该值时,如何在Golang中测试默认值?,go,Go,我正在编写一个守护进程的配置处理程序,并利用yaml包来完成这项工作。导入我的文件的工作方式如下: package daemon import ( "ioutil" "log" "gopkg.in/yaml.v2" ) type daemonConfig struct { BindAddress string `yaml:"bind_address"` BindPort int `yaml:"bind_port"` VerifyS

我正在编写一个守护进程的配置处理程序,并利用
yaml
包来完成这项工作。导入我的文件的工作方式如下:

package daemon

import (
    "ioutil"
    "log"

    "gopkg.in/yaml.v2"
)

type daemonConfig struct {
    BindAddress string `yaml:"bind_address"`
    BindPort    int    `yaml:"bind_port"`
    VerifySSL   bool   `yaml:"verify_ssl"`
}
*config.VerifySSL = true
我可以轻松地从YAML文件中解组数据,如下所示:

func (config *daemonConfig) getConf() *daemonConfig {
    yamlFile, err := ioutil.ReadFile("config.yaml")
    if err != nil {
        log.Fatal("Unable to open config.yaml:", err)
    }
    err = yaml.Unmarshal(yamlFile, config)
    if err != nil {
        log.Fatal("Failed to unmarshall config.yaml:", err)
    }
    config, err = setDefaults(config)

    return config
}
我的问题是关于我的自定义setDefaults函数。如果没有提供字段,如
bind\u port
bind\u address
,我只想将它们设置为默认值:

func setDefaults(config *daemonConfig) (*daemonConfig, error) {
    if len(config.BindAddress) <= 0 {
        config.BindAddress = "0.0.0.0"
    }
    if config.BindPort == 0 {
        config.BindPort = 9999
    }

    return config, nil
}
如果这个字段不存在于正在解组的YAML字段中,我将如何检查该行是否存在?我可以手动读取文件并首先检查该参数,但我想知道是否有一种更优雅的方式来处理我所拥有的;否则,我将使用
ioutil
和字符串检查来完成。谢谢

多亏了,我发现我可以用指针来做这个。如果我将我的
VerifySSL
字段更改为使用指针并添加
ommitempty

type daemonConfig struct {
    BindAddress string `yaml:"bind_address"`
    BindPort    int    `yaml:"bind_port"`
    VerifySSL   *bool  `yaml:"verify_ssl",omitempty`
}
我可以简单地取消对结构中的字段的引用,以获得
yaml
unmarshalled的真实值。设置默认值非常简单,如下所示:

func setDefaults(config *daemonConfig) (*daemonConfig, error) {
    if len(config.BindAddress) <= 0 {
        config.BindAddress = "0.0.0.0"
    }
    if config.BindPort == 0 {
        config.BindPort = 9999
    }
    if config.VerifySSL == nil {
        ssl := true
        config.VerifySSL = &ssl
    }

    return config, nil
}
这就是取消对
nil
指针的引用。我已经更新了解决方案,使其包含更易于管理的内容。

多亏了,我发现我可以使用指针来实现这一点。如果我将我的
VerifySSL
字段更改为使用指针并添加
ommitempty

type daemonConfig struct {
    BindAddress string `yaml:"bind_address"`
    BindPort    int    `yaml:"bind_port"`
    VerifySSL   *bool  `yaml:"verify_ssl",omitempty`
}
我可以简单地取消对结构中的字段的引用,以获得
yaml
unmarshalled的真实值。设置默认值非常简单,如下所示:

func setDefaults(config *daemonConfig) (*daemonConfig, error) {
    if len(config.BindAddress) <= 0 {
        config.BindAddress = "0.0.0.0"
    }
    if config.BindPort == 0 {
        config.BindPort = 9999
    }
    if config.VerifySSL == nil {
        ssl := true
        config.VerifySSL = &ssl
    }

    return config, nil
}

这就是取消对
nil
指针的引用。我已更新解决方案,使其包含更易于管理的内容。

您是否尝试使用指针?我不确定是否遵循,抱歉;如果默认情况下指向结构中未编组的字段的指针仍指向
false
值,该指针将如何帮助?我不知道用户是否显式地设置了
false
,或者它实际上是一个空字段,我不想意外地覆盖他们的设置。抱歉,我太过密集。如果
yaml
的工作方式与
json
包类似,那么您可以有一个
VerifySSL*bool
字段,它将默认为
nil
,而不是(指向
false的指针)。可能还需要
省略empty
标志。是否尝试使用指针?我不确定是否遵循,抱歉;如果默认情况下指向结构中未编组的字段的指针仍指向
false
值,该指针将如何帮助?我不知道用户是否显式地设置了
false
,或者它实际上是一个空字段,我不想意外地覆盖他们的设置。抱歉,我太过密集。如果
yaml
的工作方式与
json
包类似,那么您可以有一个
VerifySSL*bool
字段,它将默认为
nil
,而不是(指向
false的指针)。可能还需要
省略empty
标志。