Skip to content

常见问题

我必须传指针吗?

值或指针都可以。Check 接受 interface{}——指针会被自动解引用, nil 被视为"没有什么需要校验",不会 panic。

go
govalid.Check(form)   // 值
govalid.Check(&form)  // 指针

如果你需要带指针接收者的 Validate() error 方法被触发,请传指针。 值接收者两种调用都会触发。

怎么把字段做成"可选但格式校验"?

省略 required 即可。格式型校验器(emailmobile……)会把空 字符串视为通过:

go
type Form struct {
    Backup string `valid:"email"` // 允许空,但有值时必须合法
}

怎么强制 boolean 必须为 true

required。govalid 的 requiredbool 视为"非零值",也就是 true

go
type Terms struct {
    Accepted bool `valid:"required" label:"服务条款"`
}

怎么逐元素校验切片?

把它写成 struct 切片,然后给该 struct 的字段加标签。govalid 会自动 遍历元素:

go
type Item struct {
    Name string `valid:"required"`
}
type Order struct {
    Items []Item `valid:"required"`
}

[]*Item(指针切片)目前不支持逐元素校验——请用 []Item 或自己 loop。

怎么取回字段原始的错误类型?

目前 *ErrContext 没有暴露 Unwrap,所以 errors.As 无法穿透到 Validate() 方法返回的底层错误。两种常见绕开方案:

  • 把需要的数据编码进错误字符串。
  • Validate() 通过侧通道返回错误(例如把它们记到 form 结构体 本身上)。

这是已知的粗糙之处——如果它困扰你,欢迎提 issue。

为什么 min/max 忽略我的 bool 字段?

因为它们只对数值类型生效(有符号/无符号整型与浮点数)。布尔字段 请用 requiredlist:true,false

为什么 equal 是按字符串比较?

equalfmt.Sprintf("%v", …) 把两边都字符串化。这让它能跨异构 类型工作(int vs string),代价是无法捕捉细微的类型不匹配。 如果你需要严格的类型相等比较,写一个自定义校验器即可。

我能在同一个结构体上跑多次校验吗?

可以。从调用方角度看 govalid 是无状态的——Check 可以用同一个值 反复调用。每次调用都会重新遍历整个结构体。

在热加载校验器 map 的场景下安全吗?

CheckerserrorTemplateChinese 等的读取在没有写者时是并发安全的。 如果你必须在运行时改动它们,请用自己的互斥锁包好,并在切换时暂停 所有正在飞的请求。

在哪里报 bug?

github.com/wuhan005/govalid/issues

基于 MIT 协议发布。