包含以下字段的 struct 怎么解决_Go字段校验库的使用 - Go语言中文社区

包含以下字段的 struct 怎么解决_Go字段校验库的使用


最近由于工作需要,了解了一下go目前比较常用的字段校验库,整理了一下GitHub上Star比较多的库的用法,如下:

1.常用go字段校验库

https://github.com/go-playground/validatorba3760890cdb7d38269f1e43a61580d6.png

https://github.com/asaskevich/govalidator

273ddde4574ec77ae08091cd9c3a9758.png

https://github.com/gookit/validate

866865949b946541b8f30704528025e9.png

https://github.com/smokezl/govalidators

d2b533aee6cc717f0cc9a3c3e273d783.png

2.常用校验库对比根据星星数,网上使用推荐,活跃程度以及维护情况来看,目前使用比较多的是validator和govalidator playground/validator包:基于标签对结构体和单个字段进行校验
  • 支持struct,slice,array和map等等数据类型;

  • 支持struct的嵌套检查;

  • 支持处理自定义字段类型,例如sql driver Valuer;

  • 参数校验错误时输出是英文,支持转换成中文;

  • 支持自定义验证标签和函数;

  • gin Web框架的默认验证器。

asaskevich/govalidator包:基于validator.js对结构体,字符串和collections进行校验
  •  使用方式简单易懂,直接调用相应的函数即可;

  • 包含丰富的检验函数;

  • 支持struct的嵌套检查;

  • 支持自定义tag与自定义校验函数;

  • govalidator除了支持校验,还支持较为丰富的字符串裁剪、处理、正则等功能,以及若干类型转换功能。

3. playground/validator库使用

A. 常用标记及说明

bd0efeb27971e557d321ed77f45e4b64.png

e4e5746c998758afb30c32e5481af50f.png

1bf3237b262a7c68a2a38a1c48cb3718.png

a1def8609903dcc92daa23c0407a641e.png

B. 用法示例

package mainimport (  "fmt"  "github.com/go-playground/locales/zh"  "github.com/go-playground/universal-translator"  "github.com/go-playground/validator/v10"  zh_translations "github.com/go-playground/validator/v10/translations/zh")// User contains user informationtype User struct {  FirstName      string     `validate:"required"`  LastName       string     `validate:"required"`  Age            uint8      `validate:"gte=0,lte=130"`  Email          string     `validate:"required,email"`  FavouriteColor string     `validate:"iscolor"`                // alias for 'hexcolor|rgb|rgba|hsl|hsla'  Addresses      []*Address `validate:"required,dive,required"` // a person can have a home and cottage...}// Address houses a users address informationtype Address struct {  Street string `validate:"required"`  City   string `validate:"required"`  Planet string `validate:"required"`  Phone  string `validate:"required"`}// use a single instance of Validate, it caches struct infovar validate *validator.Validatefunc main() {  validate = validator.New()  validateStruct()  validateVariable()}func validateStruct() {  address := &Address{    Street: "Eavesdown Docks",    Planet: "Persphone",    Phone:  "none",  }  user := &User{    FirstName:      "Badger",    LastName:       "Smith",    Age:            135,    Email:          "Badger.Smith@gmail.com",    FavouriteColor: "#000-",    Addresses:      []*Address{address},  }  // returns nil or ValidationErrors ( []FieldError )  err := validate.Struct(user)  if err != nil {    // this check is only needed when your code could produce    // an invalid value for validation such as interface with nil    // value most including myself do not usually have code like this.    if _, ok := err.(*validator.InvalidValidationError); ok {      fmt.Println(err)      return    }    for _, err := range err.(validator.ValidationErrors) {      fmt.Println(err.Namespace())      fmt.Println(err.Field())      fmt.Println(err.StructNamespace())      fmt.Println(err.StructField())      fmt.Println(err.Tag())      fmt.Println(err.ActualTag())      fmt.Println(err.Kind())      fmt.Println(err.Type())      fmt.Println(err.Value())      fmt.Println(err.Param())      fmt.Println()    }    // from here you can create your own error messages in whatever language you wish    return  }  // save user to database}func validateVariable() {  //1.string  myEmail := "joeybloggs.gmail.com"  errs := validate.Var(myEmail, "required,email")  processErr(errs)  subString := "hello,china"  errs = validate.Var(subString, "contains=china1")  processErr(errs)  syntaxCheck1 := ""  syntaxCheck2 := "12312rdq2fwefdf"  syntaxCheck3 := "45"  errs = validate.Var(syntaxCheck1, "required,gt=0,lt=10")  processErr(errs)  errs = validate.Var(syntaxCheck2, "required,gt=0,lt=10")  processErr(errs)  errs = validate.Var(syntaxCheck3, "required,gt=0,lt=10")  processErr(errs)  //2.int  numTest := 5  errs = validate.Var(numTest,"required,max=2")  processErr(errs)  //3.数组和切片  slice := make([]int, 2)  slice[0] = 10  slice[1] = 10  errs = validate.Var(slice, "unique")  processErr(errs)  //4.map  dict := make(map[string]int)  dict["go"] = 100  dict["c"] = 50  errs = validate.Var(dict,"gt=1,dive,keys,required,endkeys,max=80")  processErr(errs)  //5.VarWithValue方法:两个变量的比较  errs = validate.VarWithValue(1,2, "eqfield")  processErr(errs)  //6.错误处理  errs = validate.Struct(numTest)  processErr(errs)  //7.自定义约束  palindromeStr := "djffj"  validate.RegisterValidation("palindrom", checkPalindrome)  errs = validate.Var(palindromeStr, "palindrom")  processErr(errs)  //8.转换成中文  //中文翻译器  zh_ch := zh.New()  uni := ut.New(zh_ch)  trans, _ := uni.GetTranslator("zh")  //验证器注册翻译器  zh_translations.RegisterDefaultTranslations(validate,trans)  errs = validate.Var("124.23.234.1234", "ip")  if errs != nil {    for _, validationErrs := range errs.(validator.ValidationErrors) {      fmt.Println(validationErrs.Translate(trans))    }  }  charater := "中文"  errs = validate.Var(charater, "alphaunicode")  processErr(errs)  cc := "中国"  errs = validate.Var(cc,"alphanumunicode")  processErr(errs)  errs = validate.Var(cc,"alphanum")  processErr(errs)  return}func processErr(err error) {  if err == nil {    return  }  if invalid, ok := err.(*validator.InvalidValidationError); ok {    fmt.Println("param error :", invalid)    return  }  for _, validationErrs := range err.(validator.ValidationErrors) {    fmt.Println(validationErrs)  }}func reverseString(s string) string {  runes := []rune(s)  for from, to := 0, len(runes)-1; from < to; from, to = from+1, to-1 {    runes[from], runes[to] = runes[to], runes[from]  }  return  string(runes)}func checkPalindrome(f1 validator.FieldLevel) bool {  value := f1.Field().String()  return value == reverseString(value)}

4. asaskevich/govalidator库的使用

A. 常用内置函数

85305ce8a3c712f986b958a390ac2c3d.png

7263230444f1e9b155fa583a77eb51cd.png

B. govalidator专门提供了一个函数govalidator.ValidateStruct(),用于校验struct的元素 

  • struct元素只支持部分常用的校验;

  • struct元素必须是导出型,也就是必须大写字母开头,govalidator才会去理会;

  • struct元素匹配较为智能,比如range(min|max)不仅支持string也支持int类型

C. 用法示例

package mainimport (  "fmt"  "github.com/asaskevich/govalidator")type Foo struct {  A string `valid:"ipv4"`  B string `valid:"mac"`  C int `valid:"range(0|100)"`}type bar struct {  X string `valid:"ipv4"`  Foo `valid:",required"`}func main() {  govalidator.SetFieldsRequiredByDefault(true)  // 判断字符串值是否为合法的IPv4地址  ip4 := "192.168.1.1"  fmt.Println(govalidator.IsIPv4(ip4)) // true  // 判断字符串值是否为合法的MAC  mac := "aa:bb:cc:dd:ee:ffffff"  fmt.Println(govalidator.IsMAC(mac)) // false  // 判断数字是否在指定范围内  dig := 101    // string类型也可以用  fmt.Println(govalidator.InRange(dig, 0, 100)) // false  //struct  b := bar{    X: "192.168.1.1",  }  b.Foo.A = "192.168.1.1.12"  b.Foo.B = "aa:bb:cc:dd:ee:ff"  b.Foo.C = 100  result, err := govalidator.ValidateStruct(b)  if err != nil {    fmt.Println("error: " + err.Error())  }  fmt.Println(result)  //类型转换  a := "12131"    fmt.Println(govalidator.ToFloat(a))}
版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/weixin_39755003/article/details/111130483
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2021-05-18 05:50:15
  • 阅读 ( 869 )
  • 分类:Go

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢