Go语言中validation库不能校验零值问题的解决方法
作者:十三度灰
问题描述
在用于绑定的结构体中,通常会使用 validator
库进行参数的校验,比如:
type User struct { Name string `json:"name" binding:"required" example:"kkk"` Age int `json:"age" binding:"required" example:"18"` Status int `json:"status" binding:"required" example:"1"` }
我们规定前端传递的参数中,user、age、status 参数都为必填
然后在 Handler
函数中使用 ShouldBindJSON
绑定参数,如下:
func handlerT(c *gin.Context) { var user User if err := c.ShouldBindJSON(&user); err != nil { fmt.Println(err) c.JSON(400, gin.H{"msg": "参数错误" + err.Error()}) return } }
完整代码如下:
package main import ( "fmt" "github.com/gin-gonic/gin" ) type User struct { Name string `json:"name" binding:"required" example:"kkk"` Age int `json:"age" binding:"required" example:"18"` Status int `json:"status" binding:"required" example:"1"` } func handlerT(c *gin.Context) { var user User if err := c.ShouldBindJSON(&user); err != nil { fmt.Println(err) c.JSON(400, gin.H{"msg": "参数错误" + err.Error()}) return } c.JSON(200, gin.H{"msg": "ok", "data": user}) } func main() { r := gin.Default() r.POST("/user", handlerT) // 监听 err := r.Run(":9090") if err != nil { panic(err.Error()) } }
使用 Postman 去调试接口:
可以看到没有问题,但是当 status 值为 0 的时候,参数校验就会不通过:
解决方法
原因是:Go 中会给结构体中没有赋值的字段赋予零值(int 类型默认 0、string 类型默认 "",等等),标签写成 require
时,如果传递零值,validator
校验的时候就会认为没有传递这个字段,进而报错
解决方法也很简单,既然原因是因为字段的类型零值是 0,那选用默认值不是 0 的数据类型,而且也要是数值类型
所以,解决方法就是:把 int
类型改为 *int
类型,使用 int 的指针类型,零值为 nil,这样传递的时候就能成功绑定
结构体改为:
type User struct { Name string `json:"name" binding:"required" example:"kkk"` Age int `json:"age" binding:"required" example:"18"` Status *int `json:"status" binding:"required" example:"1"` }
再使用 Postman 调试:
可以看到成功绑定,但是这样会有一个问题:
在绑定成功后,我们可能需要针对 user.Status 字段写一些逻辑,比如 status 值为 1 时表示为正常状态,0 为非正常状态,那么简单的示例为:
可以看到,user.Status == 0
这一段报错了,因为 user.Status
是指针类型,不能直接与 int 类型比较,要想比较只能加上地址符 *
,或者再使用一个变量接收由 *int
类型转换来的 int
类型
总结
当遇到 validator
库无法校验零值时,把数据类型换为对应的指针类型即可正常接收,但是在后续逻辑中,不能直接用这个指针类型的值进行常规运算,要么加上地址符 *
要么用中间变量接收转换后的值
以上就是Go语言中validation库不能校验零值问题的解决方法的详细内容,更多关于Go validation不能校验零值的资料请关注脚本之家其它相关文章!