在Golang中处理多个错误的最佳做法

时间:2018-10-05 13:55:23

标签: go

我正在编写一些代码来解析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(在评论中出现)。当我说动态时,我的意思是可以有任意数量的controlling_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"

1 个答案:

答案 0 :(得分:2)

没有官方的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)
}