【问题标题】:Best Practice for Handling Multiple Errors in GolangGolang 中处理多个错误的最佳实践
【发布时间】:2019-03-11 01:21:57
【问题描述】:

我正在编写一些代码来解析 YAML 文件并验证其中的数据。如果找到的值不符合要求,每个解析器都会返回错误。现在我正在创建一个错误数组并将每个调用的返回设置为数组中的不同索引。我目前的实现是有效的,但它似乎是错误的,我想看看是否有更好的方法来实现这一点。

这是一个例子

func createStruct(yamlMap map[interface{}]interface{}) (myStruct, error) {
    errs := make([]error, 6)
    s := myStruct{}

    s.Name, errs[0] = getString(yamlMap, "name", true)
    s.Tag, errs[1] = getIntValidRange(yamlMap, "tag", 1, 4094, true)
    s.TaggedPorts, errs[2] = getStringPortList(yamlMap, "tagged_ports", true)
    s.UntaggedPorts, errs[3] = getStringPortList(yamlMap, "untagged_ports", true)
    s.IP, errs[4] = getIPString(yamlMap, "ip", true)
    s.Netmask, errs[5] = getIPString(yamlMap, "netmask", true)

    return s, structCreateErrorChecker(errs)
}

我不在每个函数之后处理每个错误的原因是因为我想尝试先解析所有内容,然后收集所有错误并记录它们。这就是 structCreateErrorChecker() 所做的。

这是我要解析的 YAML(它出现在 cmets 中)。当我说动态时,我的意思是可以有任意数量的这些 control_bridge 部分,并且每个 vlan 部分可以有任意数量的 vlan。

controlling_bridge_1:
    ip:    "1.1.1.1"
    ports: ["1","2"]
    vlans:
        vlan01:
            name:  "vlan1"
            tag:   1001
            ports: ["1"]
            ip:    "2.2.2.2"
        vlan02:
            name:  "vlan02"
            tag:   1002
            ports: ["3", "4"]
            ip:    "3.3.3.1"

controlling_bridge_2:
    ip:    "1.1.1.1"
    ports: ["1","2"]
    vlans:
        vlan01:
            name:  "vlan1"
            tag:   1001
            ports: ["1"]
            ip:    "2.2.2.2"
        vlan02:
            name:  "vlan02"
            tag:   1002
            ports: ["3", "4"]
            ip:    "3.3.3.1"

【问题讨论】:

  • 你为什么不直接将你的(显然的)YAML 输入解组到你想要的结构中,而不是使用地图中这种令人困惑的getString() 方法?
  • 我最初尝试将 YAML 直接解组到我的结构中,但由于 YAML 文件的动态特性,我遇到了很多麻烦。因此,我将其解组为一个接口{} 并对其进行解析。
  • 如果可以这样解析,就可以使用unmarshaling解析。没有逻辑上的区别。
  • 你的 YAML 输入是“动态的”怎么样?
  • 用我的 YAML 信息更新了我的帖子。

标签: go


【解决方案1】:

没有官方的yaml库,但是gopkg.in/yaml.v2是个不错的选择。要解组给定的 yaml,您可以定义结构并将 yaml 标签添加到属性中。

通过为您的网桥和 vlan 使用映射并为端口使用数组,您可以毫无问题地解组数据。

当您使用地图时,请记住迭代地图并不能保证返回元素的顺序。

这个程序会解组你给定的结构:

package main

import (
    "fmt"
    "log"

    yaml "gopkg.in/yaml.v2"
)

var data = `
controlling_bridge_1:
    ip:    "1.1.1.1"
    ports: ["1","2"]
    vlans:
        vlan01:
            name:  "vlan1"
            tag:   1001
            ports: ["1"]
            ip:    "2.2.2.2"
        vlan02:
            name:  "vlan02"
            tag:   1002
            ports: ["3", "4"]
            ip:    "3.3.3.1"

controlling_bridge_2:
    ip:    "1.1.1.1"
    ports: ["1","2"]
    vlans:
        vlan01:
            name:  "vlan1"
            tag:   1001
            ports: ["1"]
            ip:    "2.2.2.2"
        vlan02:
            name:  "vlan02"
            tag:   1002
            ports: ["3", "4"]
            ip:    "3.3.3.1"
`

type Bridge struct {
    IP    string   `yaml:"ip"`
    Ports []string `yaml:"ports"`
    Vlans map[string]Vlan
}

type Vlan struct {
    Name  string   `yaml:"name"`
    Tag   string   `yaml:"tag"`
    Ports []string `yaml:"ports"`
    IP    string   `yaml:"ip"`
}

func main() {
    bridges := map[string]Bridge{}

    err := yaml.Unmarshal([]byte(data), &bridges)
    if err != nil {
        log.Fatalf("error: %v", err)
    }

    fmt.Printf("%+v\n", bridges)
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-09-12
    • 2017-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-08
    • 2016-06-06
    • 1970-01-01
    相关资源
    最近更新 更多