【问题标题】:Typed map does not support indexing类型化地图不支持索引
【发布时间】:2014-09-14 06:53:23
【问题描述】:

我想扩展 go-validator 以返回更好的类型:

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
}

当我正在为此编写测试时,我遇到了一个问题,即类型化映射 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 类型,但得到“不可能的类型断言”。

我的方法有什么问题? 我怎样才能让索引恢复工作?

【问题讨论】:

标签: go type-conversion


【解决方案1】:

您的 err 变量似乎是用 error 类型初始化的。当你这样做时

err, ok := Validate(Value{}).(Error)

您只需检查 err 是否实际上是 Error。如果您将 err 那里更改为 errs,它应该可以工作。

游乐场示例:http://play.golang.org/p/ljNroPzVbd

【讨论】:

  • 谢谢!你是对的。我在上面某处定义了var err error:= 没有覆盖 var 类型...
  • 您实际上根本无法在 Go 中“覆盖”类型。您可以将不同类型的值存储在接口变量中,但它们仍将具有静态类型的接口。也就是说,两个指针的“结构”,第一个指向值,另一个指向类型信息。有关详细信息,请参阅Russ Cox's article
猜你喜欢
  • 2018-10-29
  • 1970-01-01
  • 2014-10-02
  • 1970-01-01
  • 2018-09-16
  • 1970-01-01
  • 2014-10-05
  • 2023-04-01
相关资源
最近更新 更多