Skip to content

FAQ

Can I use it on a value or do I need a pointer?

Both work. Check accepts interface{} — pointers are dereferenced automatically, and nil is treated as "nothing to validate" rather than a panic.

go
govalid.Check(form)   // value
govalid.Check(&form)  // pointer

If you need a Validate() error method with a pointer receiver to fire, pass a pointer. Value receivers fire either way.

How do I make a field optional but still format-checked?

Skip the required rule. Format-style checkers (email, mobile, …) treat the empty string as valid:

go
type Form struct {
    Backup string `valid:"email"` // empty allowed, must be valid if set
}

How do I require a boolean to be true?

Use required. govalid's required interprets a bool field as "non-zero", which means true:

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

How do I validate a slice element-by-element?

Make it a slice of structs and tag the struct's fields. govalid walks elements automatically:

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

For []*Item (slice of pointers) per-element validation isn't supported today — use []Item or loop manually.

How do I get a field's original error type back?

Today *ErrContext doesn't expose Unwrap, so type-asserting through errors.As won't reach a Validate() method's underlying error. Two common workarounds:

  • Encode the data you need in the error string.
  • Return errors via a side channel from Validate() (e.g. embed them on the form struct itself).

This is a known rough edge — please open an issue if it bites you.

Why do min/max ignore my bool field?

Because they only act on numeric kinds (signed/unsigned int and float). For booleans, prefer required or list:true,false.

Why is equal comparing strings?

equal stringifies both sides with fmt.Sprintf("%v", …). This makes it work across heterogeneous types (int vs string), at the cost of not catching subtle type mismatches. Write a custom checker if you need strict typed equality.

Can I run multiple validators on the same struct?

Yes. govalid is stateless from the caller's perspective — Check can be called repeatedly with the same value. Each call walks the struct afresh.

Is the library safe for use with hot-reloaded checker maps?

Reads of Checkers, errorTemplateChinese, etc. are concurrent-safe as long as no writer is active. If you must mutate at runtime, wrap the mutations in your own mutex and pause traffic while the swap happens.

Where do I report bugs?

github.com/wuhan005/govalid/issues.

Released under the MIT License.