Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
List 在Go中解组Yaml时,如何设置列表中键的默认值?_List_Go_Yaml_Default - Fatal编程技术网

List 在Go中解组Yaml时,如何设置列表中键的默认值?

List 在Go中解组Yaml时,如何设置列表中键的默认值?,list,go,yaml,default,List,Go,Yaml,Default,我有一个类似下面的YAML connections: - name: demo hosts: - demo.example.com:9200 username: admin password: password ssl: true ssl_verify: true version: 7 - name: test hosts: - "test.example.com:9200" username: ad

我有一个类似下面的YAML

connections:
  - name: demo
    hosts:
      - demo.example.com:9200
    username: admin
    password: password
    ssl: true
    ssl_verify: true
    version: 7
  - name: test
    hosts:
      - "test.example.com:9200"
    username: admin
    password: password
如您所见,
ssl
ssl\u验证
未设置在列表的第二项中。我希望它们在默认情况下为
true
,但是,它不会发生。我尝试了不同的解决方案

  • Viper默认值-不工作
  • -不起作用
  • 在结构列表中手动循环。虽然这些方法处理字符串,但它不处理布尔值,因为在解组后,它们已经用
    false
    初始化,我们无法确定用户是否输入了
    false

  • 使用带有布尔值的指针。这是因为未初始化的值等于
    nil
    ,并且易于捕获。但是,在使用config struct时需要取消对指针的引用,这不是很方便。或者,可以基于解组生成的结构生成新结构

  • 使用hashmap而不是struct。这是因为空值没有初始化,但是,在访问映射元素或将映射转换为结构之前,需要对其运行检查
  • 解决方案4和5可能会奏效,但我想知道是否还有比这更好的办法


    有什么想法吗?

    您可以使用一个函数来完成这项工作:

    type Connection struct {
        Name      string
        Hosts     []string
        Username  string
        Password  string
        Ssl       *bool
        SslVerify bool
        Version   int
    }
    
    // If Ssl is nil, returns true
    // otherwise the value
    func (c Connection) IsSSL() bool {
        return c.Ssl == nil || *c.Ssl
    }
    
    type Config struct {
        Connections []Connection
    }
    
    编辑

    或者,更好的是,简单地颠倒你的布尔逻辑:

    type Connection struct {
        Name          string
        Hosts         []string
        Username      string
        Password      string
        SkipSsl       bool
        SkipSslVerify bool
        Version       int
    }
    

    通过这种方式,除非在配置中明确指出不同,否则将使用SSL,这在有人阅读配置时会非常突出。

    我明白了。我正在
    unmarshalyml
    回调中使用
    github.com/creasty/defaults

    
    type Config struct {
        Connections []Connection
    }
    
    type Connection struct {
        Name      string
        Hosts     []string
        Username  string
        Password  string
        Ssl       bool `default:"true"`
        SslVerify bool `default:"true" yaml:"ssl_verify"`
        Version   int  `version:"7"`
    }
    
    func (s *Connection) UnmarshalYAML(unmarshal func(interface{}) error) error {
        defaults.Set(s)
    
        type plain Connection
        if err := unmarshal((*plain)(s)); err != nil {
            return err
        }
    
        return nil
    }
    

    此外,此解决方案还可用于验证目的。

    您是否尝试过
    viper.SetDefault(“connections.ssl”,true)
    ?ie没有
    []
    并传入实际的布尔值而不是字符串。是的,它不起作用。它只在连接不是数组的情况下对结构有效,但这不是我所需要的。问题似乎是,在解组之前,你不知道连接集合中有多少元素,所以没有一个好方法用默认值初始化切片。您是否可以控制
    Config
    struct本身的定义?在这种情况下,将属性重命名为
    NoSsl
    nosslvify
    可能是重新设置框架的好方法。您可以先将其作为哈希映射加载,填充间隙,转储(到文件或字符串),然后使用适当的类型重新加载。这样,您就不必在运行时的其余部分进行检查。
    键入简单连接
    ,这很好。这应该包括在godoc中的解组halyaml(目前不存在)示例中。
    type Connection struct {
        Name      string
        Hosts     []string
        Username  string
        Password  string
        Ssl       *bool
        SslVerify bool
        Version   int
    }
    
    // If Ssl is nil, returns true
    // otherwise the value
    func (c Connection) IsSSL() bool {
        return c.Ssl == nil || *c.Ssl
    }
    
    type Config struct {
        Connections []Connection
    }
    
    type Connection struct {
        Name          string
        Hosts         []string
        Username      string
        Password      string
        SkipSsl       bool
        SkipSslVerify bool
        Version       int
    }
    
    
    type Config struct {
        Connections []Connection
    }
    
    type Connection struct {
        Name      string
        Hosts     []string
        Username  string
        Password  string
        Ssl       bool `default:"true"`
        SslVerify bool `default:"true" yaml:"ssl_verify"`
        Version   int  `version:"7"`
    }
    
    func (s *Connection) UnmarshalYAML(unmarshal func(interface{}) error) error {
        defaults.Set(s)
    
        type plain Connection
        if err := unmarshal((*plain)(s)); err != nil {
            return err
        }
    
        return nil
    }