【问题标题】:Convert slice of errors to a slice of structs in golang将错误切片转换为 golang 中的结构切片
【发布时间】:2018-01-04 05:04:08
【问题描述】:

我正在使用 Golang validate 库作为 API 的一部分进行一些输入错误检查(用于学习目的的愚蠢演示 API)。

当执行验证时,会返回一个 errors 切片。实际上,切片由 validate 库的结构 BadField 组成,如下所示:

type BadField struct {
    Field string
    Err   error
}

func (b BadField) Error() string {
    return fmt.Sprintf("field %s is invalid: %v", b.Field, b.Err)
}

我想传递一个更具体的切片,而不是[]error,我想要[]BadField,这样我就可以访问Field 值。

到目前为止,我找不到一种从一种转换/转换到另一种的方法。也许没有(由于 go 和 slices 的性质)。也许有一个包可以为我做到这一点。

我的初始实现

我想出的方法是遍历切片并单独投射每个元素。

errors := valueWithBadStuff.Validate()

validationErrors := make([]validate.BadField, len(errors))
for _, err := range errors {
    validationError, ok := err.(validate.BadField)
    if !ok {
        panic("badarghfiremyeyes") // S/O purposes only
    }
    validationErrors = append(validationErrors, validationError)
}

这对“简单”的东西有点渴望,但也许有一种更惯用的方式?或者更好的方法?

作为背景,我的意图(目前)是获取验证错误的片段并将其作为具有Field 名称和错误消息(即虚构的@ 987654330@字段:["field_name": "age", "Cannot be less than 0"])

在上面的循环之后,我进行 more 转换以生成带有json 标记的结构片段,这些结构片段实际上会进入客户端。额外的转换可能是重复的和毫无意义的,但现在,它纯粹是一个学习部分,我可能会在一两个小时内重构它。

【问题讨论】:

    标签: validation go casting slice


    【解决方案1】:

    没有真正“更好”的方式来做到这一点。要转换切片,您基本上必须执行您已经发现的操作。

    如果您只是将这些错误返回给客户端,您可能完全不需要进行类型转换。

    实现 JSON Marshaler 接口,您可以使您的类型自动以您想要的格式输出 JSON。例如,对于您在上面给出的格式,这将是:

    func (e BadField)  MarshalJSON() ([]byte, error) {
       return json.Marshal([]string{"field_name",e.Field,e.Err.Error()})
    }
    

    但我怀疑你可能更愿意得到类似的回应:

    [  
       {  
          "field":"age",
          "error":"msg1"
       },
       {  
          "field":"name",
          "error":"msg2"
       }
    ]
    

    为此,您可以简单地将 JSON 标记添加到结构定义中,例如

    type BadField struct {
        Field string `json:"field"`
        Err   error `json:"error"`
    } 
    

    这意味着在包含BadField 实例的[]error 切片上调用json.Marshal 将产生上述JSON。

    阅读更多关于JSON & Go的信息可能会有所帮助

    PS 考虑一下你是否希望你的方法是value or pointer receivers

    【讨论】:

    • Drat 和双 drat。我知道结构的标记(对于 json 等),在那个循环之后我实际上生成了另一个标记的结构......我希望不必重新声明结构(或修改包本身)。但是我不知道 Marshaler 接口,吸取了教训。谢谢!
    猜你喜欢
    • 2019-03-09
    • 2021-08-18
    • 2012-02-25
    • 2020-09-12
    • 1970-01-01
    • 2016-11-29
    • 1970-01-01
    • 2017-02-19
    • 2022-01-19
    相关资源
    最近更新 更多