在 Golang 中,我们可以使用 struct 和 map 来表示复杂的数据结构。当需要对这些数据进行验证时,我们可以利用第三方库如 go-playground/validator.v10 来实现基于规则的验证。
下面是一个示例代码,演示了如何通过自定义标签和验证器来对 struct 和 map 进行验证:
import (
"errors"
"fmt"
"github.com/go-playground/validator/v10"
)
type Person struct {
Name string `validate:"required,min=2,max=20"`
Age int `validate:"required,min=0,max=150"`
}
func ValidateMap(m interface{}) error {
validate := validator.New()
// 注册自定义标签
validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
return fld.Tag.Get("mapkey")
})
// 注册自定义验证器
validate.RegisterValidation("person", func(fl validator.FieldLevel) bool {
m, ok := fl.Top().(map[string]interface{})
if !ok {
return false
}
p := &Person{}
for k, v := range m {
switch k {
case "name":
if name, ok := v.(string); ok {
p.Name = name
} else {
return false
}
case "age":
if age, ok := v.(int); ok {
p.Age = age
} else {
return false
}
default:
continue
}
}
err := validate.Struct(p)
if err != nil && err.(validator.ValidationErrors)[0].Tag() == "required" && len(err.(validator.ValidationErrors)) == 1 {
return true
}
return err == nil
})
// 对 map 进行验证
if err := validate.Var(m, "required,person"); err != nil {
return err
}
return nil
}
func main() {
m := map[string]interface{}{
"name": "Tom",
"age": 20,
}
if err := ValidateMap(m); err != nil {
fmt.Println("Validation failed:", err)
return
}
fmt.Println("Validation passed")
}
在上述示例中,我们定义了一个 Person 结构体,其中包含了 Name 和 Age 两个字段,并使用自定义标签来指定验证规则。接着,我们实现了一个名为 ValidateMap() 的函数,用于对给定的 map 进行验证。
在该函数中,我们首先注册了一个自定义标签和验证器。其中,自定义标签用于指定 map 中各个键的名称;而自定义验证器则用于将 map 转换为 Person 实例,并进行验证。
最后,在主函数中调用 ValidateMap() 函数来对给定的 map 进行验证。如果验证失败,则会输出错误信息;否则会输出 “Validation passed” 表示验证通过。




