Go語言中validation庫不能校驗(yàn)零值問題的解決方法
問題描述
在用于綁定的結(jié)構(gòu)體中,通常會(huì)使用 validator 庫進(jìn)行參數(shù)的校驗(yàn),比如:
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"`
}我們規(guī)定前端傳遞的參數(shù)中,user、age、status 參數(shù)都為必填
然后在 Handler 函數(shù)中使用 ShouldBindJSON 綁定參數(shù),如下:
func handlerT(c *gin.Context) {
var user User
if err := c.ShouldBindJSON(&user); err != nil {
fmt.Println(err)
c.JSON(400, gin.H{"msg": "參數(shù)錯(cuò)誤" + 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": "參數(shù)錯(cuò)誤" + err.Error()})
return
}
c.JSON(200, gin.H{"msg": "ok", "data": user})
}
?
func main() {
r := gin.Default()
r.POST("/user", handlerT)
?
// 監(jiān)聽
err := r.Run(":9090")
if err != nil {
panic(err.Error())
}
}使用 Postman 去調(diào)試接口:

可以看到?jīng)]有問題,但是當(dāng) status 值為 0 的時(shí)候,參數(shù)校驗(yàn)就會(huì)不通過:

解決方法
原因是:Go 中會(huì)給結(jié)構(gòu)體中沒有賦值的字段賦予零值(int 類型默認(rèn) 0、string 類型默認(rèn) "",等等),標(biāo)簽寫成 require 時(shí),如果傳遞零值,validator 校驗(yàn)的時(shí)候就會(huì)認(rèn)為沒有傳遞這個(gè)字段,進(jìn)而報(bào)錯(cuò)
解決方法也很簡單,既然原因是因?yàn)樽侄蔚念愋土阒凳?0,那選用默認(rèn)值不是 0 的數(shù)據(jù)類型,而且也要是數(shù)值類型
所以,解決方法就是:把 int 類型改為 *int 類型,使用 int 的指針類型,零值為 nil,這樣傳遞的時(shí)候就能成功綁定
結(jié)構(gòu)體改為:
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 調(diào)試:

可以看到成功綁定,但是這樣會(huì)有一個(gè)問題:
在綁定成功后,我們可能需要針對 user.Status 字段寫一些邏輯,比如 status 值為 1 時(shí)表示為正常狀態(tài),0 為非正常狀態(tài),那么簡單的示例為:

可以看到,user.Status == 0 這一段報(bào)錯(cuò)了,因?yàn)?user.Status 是指針類型,不能直接與 int 類型比較,要想比較只能加上地址符 * ,或者再使用一個(gè)變量接收由 *int 類型轉(zhuǎn)換來的 int 類型

總結(jié)
當(dāng)遇到 validator 庫無法校驗(yàn)零值時(shí),把數(shù)據(jù)類型換為對應(yīng)的指針類型即可正常接收,但是在后續(xù)邏輯中,不能直接用這個(gè)指針類型的值進(jìn)行常規(guī)運(yùn)算,要么加上地址符 * 要么用中間變量接收轉(zhuǎn)換后的值
以上就是Go語言中validation庫不能校驗(yàn)零值問題的解決方法的詳細(xì)內(nèi)容,更多關(guān)于Go validation不能校驗(yàn)零值的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
golang接口實(shí)現(xiàn)調(diào)用修改(值接收者指針接收者)場景詳解
這篇文章主要為大家介紹了golang接口實(shí)現(xiàn)調(diào)用修改值接收者指針接收者示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08
Go如何優(yōu)雅的關(guān)閉goroutine協(xié)程
本文將介紹首先為什么需要主動(dòng)關(guān)閉goroutine,并介紹如何在Go語言中關(guān)閉goroutine的常見套路,包括傳遞終止信號(hào)和協(xié)程內(nèi)部捕捉終止信號(hào),之后,文章列舉了需要主動(dòng)關(guān)閉協(xié)程運(yùn)行的常見場景,希望通過本文的介紹,讀者能夠掌握如何在適當(dāng)?shù)臅r(shí)候關(guān)閉goroutine2023-05-05
Golang?channel為什么不會(huì)阻塞的原因詳解
這篇文章主要為大家介紹了Golang?channel為什么不會(huì)阻塞的原因詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-07-07

