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

我正在编写一些代码来解析YAML文件并验证其中的数据。 如果找到的值不符合要求,则每个解析器都将返回错误。 现在,我正在创建一个错误数组,并将每个调用的返回值设置为数组中的另一个索引。 我当前的实现工作正常,但似乎出错了,我想看看是否有更好的方法来完成此操作。</ p>

这里是一个示例</ p>

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

s。 名称,错误[0] = getString(yamlMap,“名称”,true)
s.Tag,错误[1] = getIntValidRange(yamlMap,“ tag”,1,4094,true)
s.TaggedPorts,错误[ 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,错误[5] = getIPString(yamlMap,” netmask“,true)

返回s,structCreateErrorChecker(errs)
}
</ code> </ pre>

我不处理每个函数后的每个错误的原因是因为我想先解析所有错误,然后收集所有错误并记录下来。 那就是structCreateErrorChecker()的作用。</ p>

这是我要解析的YAML(它出现在注释中)。 当我说动态时,我的意思是说,controlling_bridge节可以有任意数量,每个vlan节可以有任意数量的vlan。</ p>

  controlling_bridge_1:
ip:“ 1.1。 1.1“
端口:[” 1“,” 2“]
vlans:
vlan01:
名称:” vlan1“
标签:1001
端口:[” 1“]
ip:” 2.2 .2.2“
vlan02:
名称:” vlan02“
标签:1002
端口:[” 3“,” 4“]
ip:” 3.3.3.1“

controlling_bridge_2:
ip: “ 1.1.1.1”
端口:[“ 1”,“ 2”]
vlans:
vlan01:
名称:“ vlan1”
标签:1001
端口:[“ 1”]
ip :“ 2.2.2.2”
vlan02:
名称:“ vlan02”
标签:1002
端口:[“ 3”,“ 4”]
ip:“ 3.3.3.1”
</ code> </ pre>
</ div>

展开原文

原文

I am writing some code that parses a YAML file and validates the data inside. Each parser returns an error if the value found does not meet the requirements. Right now I am creating an array of errors and setting the return of each call to a different index in the array. My current implementation is working, but it seems wrong and I want to see if there is a better way to accomplish this.

Here is an example

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)
}

The reason I don't handle each error after each function, is because I want to try to parse everything first and then collect all errors and log them. That is what structCreateErrorChecker() does.

Here is the YAML I am trying to parse (it's come up in the comments). When I say dynamic I mean that there can be any number of these controlling_bridge sections and each vlan section can have any number of vlans.

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"

douyalin2258
douyalin2258 您上次尝试了什么?显示您的代码。说明发生了什么,以及您的期望。
接近 2 年之前 回复
doulangyu9636
doulangyu9636 上次尝试时我没有运气,您能否指出一些可能有所帮助的东西?
接近 2 年之前 回复
doubi9255
doubi9255 好的,所以我仍然不明白为什么您不能使用常规的拆组。看起来很简单。
接近 2 年之前 回复
dszdiavv474681
dszdiavv474681 更新了有关我的YAML信息的帖子。
接近 2 年之前 回复
dou44364983
dou44364983 您的YAML输入是“动态”的吗?
接近 2 年之前 回复
douping4436
douping4436 如果可以这种方式进行解析,则可以使用封送处理来解析。没有逻辑上的区别。
接近 2 年之前 回复
duanpie4763
duanpie4763 我最初试图将YAML直接解组到我的结构中,但是由于YAML文件的动态特性,我遇到了很多麻烦。因此,我将其解组到接口{}中并进行解析。
接近 2 年之前 回复
dpprx26000
dpprx26000 为什么不只是将(显然)YAML输入编组到所需的结构中,而不是使用映射中的这种令人困惑的getString()方法呢?
接近 2 年之前 回复

1个回答

There is no official yaml library, but gopkg.in/yaml.v2 is a good choice. To unmarshal the given yaml you can define structs and add yaml tags to the attributes.

By using maps for your bridges and vlans and using arrays for the ports you can unmarshal the data without a problem.

As you are using maps, keep in mind that iterating over a map does not guarantee the order of returned elements.

This program would unmarshal your given structure:

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
", bridges)
}
duanchi4544
duanchi4544 效果很好,谢谢!
接近 2 年之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问
相关内容推荐