Golang简化错误检查

Golang简化错误检查 我在想这个验证能否进一步简化。

func (f *foo) Validate() (err error) {
  if err = conform.Strings(f); err != nil {
    return
  }

  _, err = govalidator.ValidateStruct(f)
  return
}

期待任何建议或意见。

谢谢

8 回复

是的

更多关于Golang简化错误检查的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


我建议不要使用命名返回变量,否则对我来说看起来已经足够简单了。

会返回 error 吗?

这是你指的意思吗?

func (f *foo) Validate() error {
  if err := conform.Strings(f); err != nil {
    return err
  }

  _, err := govalidator.ValidateStruct(f)
  return err
}

我会把好的代码结构保持在一级代码层级:

func (f *foo) Validate() error {
    if err := conform.Strings(f); err != nil {
        return err
    }

    if _, err := govalidator.ValidateStruct(f); err != nil {
        return err
    }

    return nil
}

我会在这个方案上停下来,它看起来相当不错。足够简洁明了。

gilcon:

func (f *foo) Validate() error {
  if err := conform.Strings(f); err != nil {
    return err
  }

  _, err := govalidator.ValidateStruct(f)
  return err
}

理想情况下,您还需要对错误信息进行装饰:fmt.Errorf("值不符合要求: %v", err)fmt.Errorf("验证失败: %v", err)。建议使用类似 github.com/pkg/errors 的库来保留原始错误信息。

fmt.Errorf("value does not conform: %v", err)
fmt.Errorf("validation failed: %v", err)

你当前的验证代码已经相当简洁,但可以通过几种方式进一步简化,具体取决于你的需求和使用的库。以下是几种可能的优化方法:

1. 使用多错误处理库(如 go-multierror

如果你的验证可能返回多个错误,可以考虑使用 go-multierror 来合并错误,这样可以在一个函数调用中处理所有验证问题。

import "github.com/hashicorp/go-multierror"

func (f *foo) Validate() error {
    var result error

    if err := conform.Strings(f); err != nil {
        result = multierror.Append(result, err)
    }

    if _, err := govalidator.ValidateStruct(f); err != nil {
        result = multierror.Append(result, err)
    }

    return result
}

2. 内联错误检查(如果不需要提前返回)

如果你的验证逻辑允许连续执行而不需要立即返回错误,可以简化错误变量的使用。

func (f *foo) Validate() error {
    if err := conform.Strings(f); err != nil {
        return err
    }
    _, err := govalidator.ValidateStruct(f)
    return err
}

3. 使用辅助函数封装重复逻辑

如果验证逻辑在多个地方重复,可以提取一个辅助函数来处理错误链。

func validateAll(validators ...func() error) error {
    for _, validator := range validators {
        if err := validator(); err != nil {
            return err
        }
    }
    return nil
}

func (f *foo) Validate() error {
    return validateAll(
        func() error { return conform.Strings(f) },
        func() error { _, err := govalidator.ValidateStruct(f); return err },
    )
}

4. 利用 govalidator 的集成(如果支持)

检查 govalidator 是否已经内置了字符串规范化功能,或者是否可以扩展其标签以包含 conform 的逻辑,从而合并两个步骤。

// 假设 govalidator 支持自定义验证器,可以在结构体标签中定义
type foo struct {
    Name string `valid:"required,conform"`
}

// 然后只需调用 govalidator
func (f *foo) Validate() error {
    _, err := govalidator.ValidateStruct(f)
    return err
}

这些方法可以根据你的具体场景选择使用。如果 conform.Stringsgovalidator.ValidateStruct 是独立的步骤,第一种或第二种简化可能更合适。

回到顶部