dso15221 2018-10-05 13:55
浏览 618
已采纳

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

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"
  • 写回答

1条回答 默认 最新

  • duanao6704 2018-10-05 18:31
    关注

    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)
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥20 有偿,求个自动门设计思路
  • ¥15 心率变异性联合机器学习预测子宫颈癌 FIGO 分期
  • ¥15 WebSocket的问题
  • ¥15 BDSBAS-B1C和B1C信号有什么不同
  • ¥15 在半圆平面内随机生成点坐标
  • ¥15 系统容量变化的几种多址方式TDMA, CDMA,FDMA,OFDMA 对比,应该给的是一个曲线 图,随着系统容量的增加,几种多址方式性能的对比 图,MATLAB程序仿真折线图
  • ¥15 用visual Studio 写c ++只运行上一个旧代码的运行结果是怎么回事
  • ¥15 系统容量变化的几种多址方式(TDMA,FDMA,OFDMA,CDMA)对比(相关搜索:曲线图)
  • ¥15 worldclim 历史及未来气候数据矫正
  • ¥15 ajax服务器不能下载