【Golang】validator库的使用

Go 复制代码
package main

import (
	"fmt"

	"github.com/go-playground/validator"
)

// MyStruct .. validate:"is-awesome"是一个结构体标签,它告诉验证器使用名为is-awesome的验证规则来验证String字段。
type MyStruct struct {
	String string `validate:"is-awesome"`
}

// use a single instance of Validate, it caches struct info
var validate *validator.Validate

func main() {

	validate = validator.New()
	//注册一个自定义验证函数ValidateMyVal,它将被用来验证标签为is-awesome的字段。
	validate.RegisterValidation("is-awesome", ValidateMyVal)

	s := MyStruct{String: "awesome"}

	err := validate.Struct(s)
	if err != nil {
		fmt.Printf("Err(s):%+v\n", err)
	}

	s.String = "not awesome"
	err = validate.Struct(s)
	if err != nil {
		fmt.Printf("Err(s):\n%+v\n", err)
	}
}

// ValidateMyVal implements validator.Func
func ValidateMyVal(fl validator.FieldLevel) bool {
	return fl.Field().String() == "awesome"
}

custom-validation 结果

Err(s):
Key: 'MyStruct.String' Error:Field validation for 'String' failed on the 'is-awesome' tag

示例代码2

custom

Go 复制代码
package main

import (
	"database/sql"
	"database/sql/driver"
	"fmt"
	"reflect"

	"github.com/go-playground/validator/v10"
)

// DbBackedUser 用户结构体,由数据库支持
type DbBackedUser struct {
	Name sql.NullString `validate:"required"` // 可以为NULL的字符串,验证规则为必填
	Age  sql.NullInt64  `validate:"required"` // 可以为NULL的整数,验证规则为必填
}

// 使用单一实例的验证器,它缓存结构体信息
var validate *validator.Validate

func main() {
	// 创建一个新的验证器实例
	validate = validator.New()

	// 注册所有sql.Null*类型,使用自定义的ValidateValuer函数
	validate.RegisterCustomTypeFunc(ValidateValuer, sql.NullString{}, sql.NullInt64{}, sql.NullBool{}, sql.NullFloat64{})

	// 构建对象进行验证
	// Name字段为空字符串但Valid为true,表示非NULL;Age字段为0且Valid为false,表示NULL
	x := DbBackedUser{Name: sql.NullString{String: "", Valid: true}, Age: sql.NullInt64{Int64: 0, Valid: false}}

	// 对x进行结构体验证
	err := validate.Struct(x)

	// 如果验证失败,打印错误信息
	if err != nil {
		fmt.Printf("Err(s):\n%+v\n", err)
	}
}

// ValidateValuer实现了validator.CustomTypeFunc接口
func ValidateValuer(field reflect.Value) interface{} {
	// 如果field实现了driver.Valuer接口
	if valuer, ok := field.Interface().(driver.Valuer); ok {
		// 尝试获取valuer的值
		val, err := valuer.Value()
		if err == nil {
			return val // 如果没有错误,返回值
		}
		// 如果有错误,可以根据需要处理
	}
	return nil // 如果没有实现Valuer接口或有错误,返回nil
}
Go 复制代码
// Struct validates a structs exposed fields, and automatically validates nested structs, unless otherwise specified.
//
// It returns InvalidValidationError for bad values passed in and nil or ValidationErrors as error otherwise.
// You will need to assert the error if it's not nil eg. err.(validator.ValidationErrors) to access the array of errors.
func (v *Validate) Struct(s interface{}) error {
	return v.StructCtx(context.Background(), s)
}

// StructCtx validates a structs exposed fields, and automatically validates nested structs, unless otherwise specified
// and also allows passing of context.Context for contextual validation information.
//
// It returns InvalidValidationError for bad values passed in and nil or ValidationErrors as error otherwise.
// You will need to assert the error if it's not nil eg. err.(validator.ValidationErrors) to access the array of errors.
func (v *Validate) StructCtx(ctx context.Context, s interface{}) (err error) {

	val := reflect.ValueOf(s)
	top := val

	if val.Kind() == reflect.Ptr && !val.IsNil() {
		val = val.Elem()
	}

	if val.Kind() != reflect.Struct || val.Type().ConvertibleTo(timeType) {
		return &InvalidValidationError{Type: reflect.TypeOf(s)}
	}

	// good to validate
	vd := v.pool.Get().(*validate)
	vd.top = top
	vd.isPartial = false
	// vd.hasExcludes = false // only need to reset in StructPartial and StructExcept

	vd.validateStruct(ctx, top, val, val.Type(), vd.ns[0:0], vd.actualNs[0:0], nil)

	if len(vd.errs) > 0 {
		err = vd.errs
		vd.errs = nil
	}

	v.pool.Put(vd)

	return
}

参考validator/_examples at master · go-playground/validator · GitHub

相关推荐
工作不忙35 分钟前
关于SwitchCase中变量定义及使用变量的一些注意事项参数传递参数时不能实现多态动态绑定的问题c++语法
开发语言·c++·windows·开源·开源软件
安祝老师37 分钟前
十四届蓝桥杯STEMA考试Python真题试卷第二套第二题
开发语言·python·算法·青少年编程·蓝桥杯
疯一样的码农2 小时前
Java初学者指南
java·开发语言
Shaun8882 小时前
Basic bash script tutorial
开发语言·bash
立黄昏粥可温2 小时前
Python 从入门到实战44(Pandas读写数据)
开发语言·python·pandas
muke_r2 小时前
C++——文件操作
开发语言·c++
cdut_suye2 小时前
Python编程探索:从基础语法到循环结构实践
开发语言·python·学习
LUwantAC2 小时前
Java学习路线:JUL日志系统(一)日志框架介绍
java·开发语言·学习
梦里水乡8572 小时前
基于MATLAB的农业病虫害识别研究
开发语言·matlab