英文:
Typed map does not support indexing
问题
我想将go-validator 扩展以返回更好的类型:
type Error map[string][]error
// 当转换为字符串时,将输出第一个错误(例如用于 JSON 响应)。
func (err Error) Error() string {
for k, errs := range err {
return fmt.Sprintf("%s value had %s", k, errs[0].Error())
}
return "no error"
}
func Validate(v interface{}) error {
if ok, errs := DefaultValidator.Validate(v); !ok {
return Error(errs)
}
return nil
}
在为此编写测试时,我遇到了一个问题,即类型为 Error
的映射似乎丢失了索引功能:
err = Validate(Value{
Foo: "bar",
Email: "foo@bar.me",
Required: "1234",
})
c.Check(err, check.IsNil)
err, ok := Validate(Value{}).(Error)
c.Check(ok, check.Equals, true)
c.Check(err["Foo"], check.DeepEquals, []error{validator.ErrMin})
c.Check(err["Email"], check.DeepEquals, []error{validator.ErrInvalid})
c.Check(err["Required"], check.DeepEquals, []error{validator.ErrZeroValue})
返回:
model/validation/validation_test.go:42: invalid operation: err["Foo"] (type error does not support indexing)
model/validation/validation_test.go:43: invalid operation: err["Email"] (type error does not support indexing)
model/validation/validation_test.go:44: invalid operation: err["Required"] (type error does not support indexing)
我还尝试将其转换为类型 map[string][]error
,但得到了"impossible type assertion"的错误。
我的方法有什么问题? 如何使索引恢复正常工作?
英文:
I want to extend go-validator to return a better type:
type Error map[string][]error
// Will output the first error when stringified (e.g. for json response).
func (err Error) Error() string {
for k, errs := range err {
return fmt.Sprintf("%s value had %s", k, errs[0].Error())
}
return "no error"
}
func Validate(v interface{}) error {
if ok, errs := DefaultValidator.Validate(v); !ok {
return Error(errs)
}
return nil
}
As I am now writing tests for this I ran into the problem that it the typed map Error
seems to have lost it indexing capabilities:
err = Validate(Value{
Foo: "bar",
Email: "foo@bar.me",
Required: "1234",
})
c.Check(err, check.IsNil)
err, ok := Validate(Value{}).(Error)
c.Check(ok, check.Equals, true)
c.Check(err["Foo"], check.DeepEquals, []error{validator.ErrMin})
c.Check(err["Email"], check.DeepEquals, []error{validator.ErrInvalid})
c.Check(err["Required"], check.DeepEquals, []error{validator.ErrZeroValue})
Returns:
model/validation/validation_test.go:42: invalid operation: err["Foo"] (type error does not support indexing)
model/validation/validation_test.go:43: invalid operation: err["Email"] (type error does not support indexing)
model/validation/validation_test.go:44: invalid operation: err["Required"] (type error does not support indexing)
I also tried to cast to type map[string][]error
but got "impossible type assertion".
What is wrong with my approach? How can I get indexing back to work?
答案1
得分: 2
你的 err 变量似乎是用 "error" 类型初始化的。当你执行
err, ok := Validate(Value{}).(Error)
时,你只是检查 err 是否实际上是一个 "Error" 类型。如果你将 err 改为 errs,它应该可以工作。
Playground 示例:http://play.golang.org/p/ljNroPzVbd
英文:
It seems like your err variable is initialised with error
type. When you do
err, ok := Validate(Value{}).(Error)
you merely check if err is actually an Error
. If you change err there to say errs, it should work.
Playground example: http://play.golang.org/p/ljNroPzVbd
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论