我正在使用 Golang validate作为 API 的一部分进行一些输入错误检查的库(用于学习目的的愚蠢的演示 API)。
当执行验证时,返回一片 error
。实际上, slice 由验证库的结构 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)
}
我想传递一个更具体的 slice ,所以我想要 []BadField
而不是 []error
以便我可以访问 字段
值。
到目前为止,我找不到一种从一个转换为另一个的方法。也许没有(由于 go 和 slices 的性质)。也许有一个包可以为我做这件事。
我的初步实现
我想出的方法是遍历 slice 并单独转换每个元素。
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
名称和错误消息的 JSON 对象数组通过管道返回给客户端 (即对于虚构的 age
字段:["field_name": "age", "Cannot be less than 0"]
)
就在上面的循环之后,我进行了more 转换以生成一段结构,这些结构用 json
标记,实际上将发送给客户端。额外的转换可能是重复且毫无意义的,但现在,它纯粹是一个学习部分,我可能会在一两个小时内重构它。
最佳答案
没有真正“更好”的方法来做到这一点。要转换 slice ,您基本上必须执行您已经发现的操作。
如果您只是将这些错误返回给客户端,您可能根本不需要对其进行类型转换。
实现 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
关于validation - 将错误片段转换为 golang 中的结构片段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45368204/