直接用 go-playground/validator 是因重复造轮子成本高、边界 case 多(如嵌套结构体、指针字段、自定义错误消息),且其为事实标准,支持 struct tag 驱动、跨字段校验、国际化提示及性能优化。

为什么直接用 go-playground/validator 而不是自己写校验逻辑
因为重复造轮子成本高、边界 case 多(比如嵌套结构体、指针字段、自定义错误消息)、且社区维护的校验器已覆盖绝大多数场景。官方库 go-playground/validator/v10 是事实标准,支持 struct tag 驱动、跨字段校验、国际化错误提示,且性能足够好(反射开销可控,v10 后做了缓存优化)。
初始化 validator 实例时别漏掉 SetTagName 和 RegisterValidation
默认只识别 validate tag,但很多人习惯用 json 或 form tag 做字段映射,结果校验不生效却查不出原因。常见错误现象:字段明明写了 required 却没报错。
- 用
v := validator.New()创建后,立刻调用v.SetTagName("validate")(显式声明,避免隐式依赖) - 需要自定义规则(如手机号、身份证号)时,必须提前注册:
v.RegisterValidation("phone", phoneValidator),否则运行时报Unknown validation: phone - 如果项目用了
mapstructure或json.Unmarshal解析数据,确保结构体字段 tag 与 validator tag 一致,不要混用json:"name"和validate:"required"—— 它们互不影响,但容易让人误以为 “写了 json tag 就自动校验了”
struct tag 写法里最容易踩的三个坑
看似简单,实际出错率极高。错误现象包括:必填字段没校验、空字符串被放过、嵌套结构体跳过校验。
初始化并管理阿里云SDK Go 客户端,涵盖 sync.Once 单例、goroutine 安全、endpoint 与 region 配置、VPC 端点及调试。
-
required对指针类型(*string)有效,但对值类型(string)默认值是空字符串,需配合omitempty或显式写required,notblank - 嵌套结构体字段要加
dive,例如:Address Address `validate:"required,dive"`,否则Address内部字段完全不校验 -
email校验只检查格式,不验证域名是否存在;url同理,不发起 HTTP 请求。别指望它替代业务层真实校验
如何让错误提示更实用,而不是只返回 Key: 'User.Email' Error:Field validation for 'Email' failed on the 'email' tag
原始错误信息对前端或日志不友好。关键不是“怎么格式化”,而是“在哪一层做”。推荐在 handler 层统一处理,而非每个校验点都手动拼字符串。
- 用
err.(validator.ValidationErrors)类型断言获取结构化错误,再遍历转成 map[string]string - 字段名默认是 struct 字段名(
Email),如需返回 API 字段名(email),得配合AliasTag或自定义FieldNameFunc - 别在 validator 初始化时就设全局错误翻译器(
ut.RegisterTranslations),除非真需要多语言;多数内部系统用英文 key + 中文 message 映射更轻量
复杂点在于嵌套错误和自定义规则的 error code 统一管理——这里没有银弹,得按项目约定设计错误码层级,validator 只负责抛出原始校验失败,别让它承担业务错误分类职责。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










