You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 14:28:24