go-playground/validator required标签验证int16类型0值失败问题咨询
问题解答
是的,你猜的没错——validator的required标签会把数值类型的零值判定为“未传入字段”,这就是Status设为0时验证失败的原因。
原因说明
validator/v10中,required标签的校验逻辑是:对于基础数据类型(比如int16、int、string等),如果字段值等于该类型的零值(int16的零值是0),就会被判定为“未设置”,从而触发required验证错误。而当你设置Status为1时,1不是int16的零值,所以validator认为字段已被显式设置,会继续校验oneof规则,验证通过后输出Success。
解决方案
根据你的需求,有两种处理方式:
1. 去掉required标签(推荐,如果你只是要限制Status的取值范围)
既然oneof=0 1 2已经包含了0这个合法值,且你允许Status被设置为0,那么required标签是多余的,直接移除即可:
package main import ( "fmt" "github.com/go-playground/validator/v10" ) type User struct { Status int16 `validate:"oneof=0 1 2"` } func main() { validate := validator.New() user := User{Status: 0} if err := validate.Struct(&user); err != nil { fmt.Println(err) } else { fmt.Println("Success") } }
这段代码运行后会输出Success,因为0符合oneof的取值范围。
2. 使用指针类型(如果需要确保字段被显式设置,即使值是0)
如果你必须确保Status字段被显式赋值(不能依赖结构体的默认零值),可以把字段类型改为*int16。此时,只要你显式给指针赋值(哪怕指向的是0),指针就不会是nil,required标签会判定字段已设置:
package main import ( "fmt" "github.com/go-playground/validator/v10" ) type User struct { Status *int16 `validate:"required,oneof=0 1 2"` } func main() { validate := validator.New() status := int16(0) user := User{Status: &status} if err := validate.Struct(&user); err != nil { fmt.Println(err) } else { fmt.Println("Success") } }
这段代码运行后也会输出Success,因为指针&status不是nil,满足required要求,同时指向的0符合oneof规则。
内容的提问来源于stack exchange,提问作者Maker Peace
相关产品推荐
相关产品推荐

