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

go-playground/validator/v10中required_if组合验证异常求助

问题根源

你遇到的验证错误,核心原因是:当ApplicantCategory不匹配时,未被选中的Person/Entity是结构体的零值实例,而非nil。validator会递归验证嵌套结构体的所有字段,哪怕外层的required_if条件不满足,内部的required标签依然会触发校验。

比如当ApplicantCategory为PERSON时,Entity字段是Entity{}(零值),其内部的Name和TaxID为空字符串,触发了自身的required验证规则,这和外层的required_if逻辑无关。

解决方案:改用指针类型

最直接的修复方式是把Person和Entity字段改为指针类型。当字段未被选中时,指针值为nil,validator默认不会对nil的结构体指针进行内部字段的验证,只会检查required_if的条件是否满足(即匹配类别时指针不为空)。

修改后的代码

package main

import (
    "fmt"
    "github.com/go-playground/validator/v10"
)

type Application struct {
    Applicants []Applicant `validate:"dive"`
}

// 将Person和Entity改为指针类型
type Applicant struct {
    ApplicantCategory string  `validate:"required,oneof=PERSON ENTITY"`
    Person            *Person `validate:"required_if=ApplicantCategory PERSON"`
    Entity            *Entity `validate:"required_if=ApplicantCategory ENTITY"`
}

type Person struct {
    Name  string `validate:"required"`
    Age   int    `validate:"required,gte=18"`
    Email string `validate:"required,email"`
}

type Entity struct {
    Name  string `validate:"required"`
    TaxID string `validate:"required"`
}

func main() {
    v := validator.New()

    data := Application{
        Applicants: []Applicant{
            {
                ApplicantCategory: "PERSON",
                // 使用&创建Person指针
                Person: &Person{
                    Name:  "John Doe",
                    Age:   25,
                    Email: "john@example.com",
                },
                // Entity默认是nil,无需赋值
            },
            {
                ApplicantCategory: "ENTITY",
                // 使用&创建Entity指针
                Entity: &Entity{
                    Name:  "Example Corp",
                    TaxID: "123456789",
                },
                // Person默认是nil,无需赋值
            },
        },
    }

    if err := v.Struct(data); err != nil {
        fmt.Println("Validation error:", err)
    } else {
        fmt.Println("Validation passed")
    }
}

验证结果

修改后运行代码,会输出Validation passed,符合预期逻辑:

  • 当类别为PERSON时,仅验证Person指针非空且内部字段合法,忽略Entity(nil)
  • 当类别为ENTITY时,仅验证Entity指针非空且内部字段合法,忽略Person(nil)

内容的提问来源于stack exchange,提问作者Mohanraj M

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 02:25:02