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

使用ozzo-validation时嵌入结构体的Validate方法未被调用

问题解决:ozzo-validation嵌套结构体验证不触发父结构体Validate方法

问题原因

ozzo-validation不会自动递归验证嵌入的结构体,即使嵌入的结构体实现了Validate方法,也需要在子结构体的验证逻辑中显式触发父结构体的验证。

修复方案

方案1:显式调用父结构体的Validate方法

修改MyOtherStruct的Validate方法,先触发嵌入的MyStruct验证,再处理自身字段验证,最后合并错误:

func (m MyOtherStruct) Validate() error {
    fmt.Println("calling MyOtherStruct validator")

    // 先执行MyStruct的验证逻辑
    if err := m.MyStruct.Validate(); err != nil {
        return err
    }

    // 验证自身字段
    err := validation.ValidateStruct(
        &m,
        validation.Field(&m.PersonnelID, validation.Match(personnelIDRegexp)),
        validation.Field(&m.City, validation.Required),
        validation.Field(&m.Comment),
        validation.Field(&m.FirstDate, validation.Date(time.DateOnly)),
        validation.Field(&m.SecondDate, validation.Date(time.DateOnly)),
    )

    return err
}

注:原代码中ValidateStruct缺少结构体实例指针参数(需补充&m);同时MyStruct的Validate方法里的uui是未定义变量,需替换为接收者m,比如&m.UUID,否则会编译报错。

方案2:通过validation.Valid()规则触发验证

在MyOtherStruct的ValidateStruct中,将嵌入的MyStruct作为字段添加validation.Valid()规则,自动触发其Validate方法:

func (m MyOtherStruct) Validate() error {
    fmt.Println("calling MyOtherStruct validator")

    err := validation.ValidateStruct(
        &m,
        // 触发MyStruct的验证
        validation.Field(&m.MyStruct, validation.Valid()),
        validation.Field(&m.PersonnelID, validation.Match(personnelIDRegexp)),
        validation.Field(&m.City, validation.Required),
        validation.Field(&m.Comment),
        validation.Field(&m.FirstDate, validation.Date(time.DateOnly)),
        validation.Field(&m.SecondDate, validation.Date(time.DateOnly)),
    )

    return err
}

这种方式更贴合ozzo-validation的字段验证风格,会自动合并父结构体与子结构体的验证错误。

额外修正:原代码变量错误

MyStruct的Validate方法中使用了未定义的uui变量,需替换为接收者m:

func (m MyStruct) Validate() error {
    fmt.Println("calling MyStruct validator")

    err := validation.ValidateStruct(
        &m,
        validation.Field(&m.UUID, is.UUID),
        validation.Field(&m.FirstUUID, validation.Required, is.UUID),
        validation.Field(&m.SecondUUID, validation.Required, is.UUID),
        validation.Field(&m.ThirdUUID, validation.Required, is.UUID),
        validation.Field(&m.Email, validation.Required, is.Email),
        validation.Field(&m.PhoneNumber, validation.Required, validation.Match(mobileRegexp)),
        validation.Field(&m.SkypeID, validation.Required),
    )

    return err
}

内容的提问来源于stack exchange,提问作者Zeinab Abbasimazar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 13:43:21