validator.Validate 返回的是 validator.ValidationErrors 类型,需类型断言后遍历获取字段名和验证标签;required 对 nil 指针无效,应改用 required_with 或 nonzero;嵌套结构体错误应使用 StructNamespace() 获取完整路径;自定义验证函数需自行 recover panic 并返回明确错误。
validator 包的
方法返回的错误不是
而是
调用
后直接用
或
,看到的是一串无法直接读取字段和原因的结构体输出,比如
—— 这其实是
类型,它实现了
接口,但内部是切片,不能当普通字符串错误处理。
实操建议:
立即学习
“
go语言免费学习笔记(深入)
”;
必须用类型断言转成
才能遍历每个字段错误
不要用
或
判断验证失败,它们对
无效(这是个切片,不是单个 error)
常见写法是:
struct tag 中
的值写错导致静默跳过验证
比如写成
看似没问题,但若 struct 字段是
类型且值为
,
不会触发 —— 因为
只对非 nil 零值生效;真正该用的是
或更明确的
(需启用
并注册),或者改用
(针对指针)。
实操建议:
立即学习
“
go语言免费学习笔记(深入)
”;
对
、
等指针类型无效(nil 时直接跳过),要用
或自定义函数
邮箱验证推荐用
,但注意它不校验 DNS 或 MX 记录,只是正则匹配,别误以为能防伪造邮箱
如果用了
,又希望空字符串也被验证,得去掉
或显式赋空字符串,否则字段被忽略
嵌套 struct 验证失败时,
返回的是全路径名,不是字段名
比如
验证失败,
返回的是
,但
才是完整路径。很多人只看
就以为字段名就是
,结果前端映射报错位置时找不到对应 key。
实操建议:
立即学习
“
go语言免费学习笔记(深入)
”;
需要精确返回前端字段路径时,优先用
(如
)
返回的是结构体中定义的字段名(如
),适合日志记录,不适合做 UI 映射
如果用了匿名嵌套(如
),
会展开,但
仍只返回最内层字段名,容易混淆
validator 注册自定义函数后,panic 报错提示里不显示函数名
比如注册了
,但验证失败时 panic 信息只说
,并不告诉你具体哪行代码抛了 panic —— 因为 validator 内部用
调用,堆栈被截断。
实操建议:
立即学习
“
go语言免费学习笔记(深入)
”;
所有自定义验证函数必须自己 recover panic,并转成明确错误(比如
)
别在自定义函数里直接调用
或
,会导致整个服务退出
调试时可临时加
事情说清了就结束
ValidateerrorvalidationErrorsValidatefmt.Println(err)log.Printf("%v", err)Key: 'User.Email' Error:Field validation for 'Email' failed on the 'email' tagvalidator.ValidationErrorserrorvalidator.ValidationErrorserrors.Iserrors.AsValidationErrorsif errs, ok := err.(validator.ValidationErrors); ok {
for _, e := range errs {
log.Printf("field %s failed on tag %s", e.Field(), e.Tag())
}
}validatevalidate:"required,email"*stringnilrequiredrequiredrequired_ifnotblankSetTagNamenonzerorequired*string*intrequired_withemailomitemptyomitemptyField()User.Profile.Address.Streete.Field()Streete.StructNamespace()Field()Streete.StructNamespace()User.Profile.Address.Streete.StructField()StreetProfile struct{ Address }StructNamespace()Field()registerCustomFunc("phone", phoneValidator)failed on the 'phone' tagreflectreturn false, fmt.Errorf("invalid phone format: %v", v)log.Fatalos.Exitdefer func(){ if r := recover(); r != nil { log.Printf("panic in phone validator: %+v", r) } }()