导读:本期聚焦于小伙伴创作的《如何做一个Golang表单校验库_Golang输入校验规则实现与复用》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《如何做一个Golang表单校验库_Golang输入校验规则实现与复用》有用,将其分享出去将是对创作者最好的鼓励。

在Golang的Web开发场景中,表单提交、接口参数传递都需要对输入数据进行合法性校验,比如判断字段是否为空、长度是否符合要求、格式是否匹配等。如果每次处理请求都单独编写校验逻辑,不仅会产生大量重复代码,还会让业务逻辑变得冗余。实现一个通用的表单校验库,把常用校验规则封装起来,支持规则灵活复用,就能很好地解决这个问题。

基础校验规则定义

首先我们需要定义校验规则的结构,每个规则需要包含校验函数、错误提示信息两个核心部分。校验函数接收待校验的值和规则参数,返回校验是否通过的结果。

package validator

import (
	"fmt"
	"reflect"
	"strings"
)

// Rule 定义单个校验规则结构
type Rule struct {
	// Check 校验函数,参数依次为待校验值、规则额外参数,返回是否通过和错误信息
	Check func(value interface{}, params string) (bool, string)
	// Msg 默认错误提示信息
	Msg string
}

// 预定义常用校验规则
var (
	// Required 必填规则,校验值不为空
	Required = Rule{
		Check: func(value interface{}, params string) (bool, string) {
			v := reflect.ValueOf(value)
			switch v.Kind() {
			case reflect.String:
				return strings.TrimSpace(v.String()) != "", "字段不能为空"
			case reflect.Ptr, reflect.Interface, reflect.Slice, reflect.Map, reflect.Array:
				return !v.IsNil(), "字段不能为空"
			default:
				return true, ""
			}
		},
		Msg: "字段不能为空",
	}

	// MinLength 最小长度规则,参数为最小长度数值
	MinLength = Rule{
		Check: func(value interface{}, params string) (bool, string) {
			str, ok := value.(string)
			if !ok {
				return false, "值必须为字符串类型"
			}
			minLen := 0
			fmt.Sscanf(params, "%d", &minLen)
			return len([]rune(str)) >= minLen, fmt.Sprintf("长度不能小于%d", minLen)
		},
		Msg: "长度不符合要求",
	}

	// MaxLength 最大长度规则,参数为最大长度数值
	MaxLength = Rule{
		Check: func(value interface{}, params string) (bool, string) {
			str, ok := value.(string)
			if !ok {
				return false, "值必须为字符串类型"
			}
			maxLen := 0
			fmt.Sscanf(params, "%d", &maxLen)
			return len([]rune(str)) <= maxLen, fmt.Sprintf("长度不能大于%d", maxLen)
		},
		Msg: "长度不符合要求",
	}
)

校验器核心结构实现

接下来需要封装校验器核心结构,支持为不同字段绑定多个校验规则,同时执行所有规则的校验,收集错误信息。

// Validator 校验器核心结构
type Validator struct {
	// rules 存储字段对应的校验规则列表,key为字段名
	rules map[string][]Rule
	// errors 存储校验错误信息,key为字段名
	errors map[string][]string
}

// NewValidator 创建新的校验器实例
func NewValidator() *Validator {
	return &Validator{
		rules:  make(map[string][]Rule),
		errors: make(map[string][]string),
	}
}

// AddRule 为指定字段添加校验规则
func (v *Validator) AddRule(field string, rule Rule, customMsg ...string) *Validator {
	// 如果传入自定义错误信息,替换规则的默认信息
	if len(customMsg) > 0 {
		rule.Msg = customMsg[0]
	}
	v.rules[field] = append(v.rules[field], rule)
	return v
}

// Validate 执行校验,传入待校验的数据结构体,返回是否全部通过
func (v *Validator) Validate(data interface{}) bool {
	// 清空之前的错误信息
	v.errors = make(map[string][]string)
	val := reflect.ValueOf(data)
	// 如果是指针类型,获取指向的元素
	if val.Kind() == reflect.Ptr {
		val = val.Elem()
	}
	// 只处理结构体类型
	if val.Kind() != reflect.Struct {
		return false
	}
	typ := val.Type()
	// 遍历所有字段
	for i := 0; i < val.NumField(); i++ {
		field := typ.Field(i)
		fieldName := field.Name
		// 获取字段对应的值
		fieldValue := val.Field(i).Interface()
		// 获取该字段绑定的所有规则
		rules, ok := v.rules[fieldName]
		if !ok {
			continue
		}
		// 执行每个规则的校验
		for _, rule := range rules {
			// 这里默认规则不需要额外参数,实际使用中可以根据规则类型传递参数
			pass, errMsg := rule.Check(fieldValue, "")
			if !pass {
				// 如果规则返回了错误信息,使用返回的信息,否则使用规则默认信息
				msg := rule.Msg
				if errMsg != "" {
					msg = errMsg
				}
				v.errors[fieldName] = append(v.errors[fieldName], msg)
			}
		}
	}
	return len(v.errors) == 0
}

// GetErrors 获取所有校验错误信息
func (v *Validator) GetErrors() map[string][]string {
	return v.errors
}

规则复用与自定义扩展

校验库的核心优势是规则可以复用,同时支持开发者根据业务需求自定义新的校验规则,只需要遵循规则的结构定义即可。

已有规则复用

同一个校验规则可以绑定到多个不同的字段,不需要重复编写校验逻辑。比如多个字段都需要必填校验,直接复用Required规则即可。

// 定义用户注册表单结构
type RegisterForm struct {
	Username string
	Password string
	Email    string
}

func main() {
	form := RegisterForm{
		Username: "test",
		Password: "123",
		Email:    "",
	}
	// 创建校验器
	v := NewValidator()
	// 复用Required规则到多个字段
	v.AddRule("Username", Required, "用户名不能为空")
	v.AddRule("Password", Required, "密码不能为空")
	v.AddRule("Email", Required, "邮箱不能为空")
	// 执行校验
	if !v.Validate(form) {
		fmt.Println("校验失败,错误信息:", v.GetErrors())
	}
}

自定义校验规则

如果预定义规则无法满足业务需求,可以自定义新的校验规则,只需要实现Rule结构的Check函数即可。

// 自定义邮箱格式校验规则
var EmailFormat = Rule{
	Check: func(value interface{}, params string) (bool, string) {
		str, ok := value.(string)
		if !ok {
			return false, "值必须为字符串类型"
		}
		// 简单的邮箱格式校验逻辑
		if !strings.Contains(str, "@") || !strings.Contains(str, ".") {
			return false, "邮箱格式不正确"
		}
		return true, ""
	},
	Msg: "邮箱格式不正确",
}

func main() {
	form := RegisterForm{
		Username: "test",
		Password: "123456",
		Email:    "testippipp.com",
	}
	v := NewValidator()
	v.AddRule("Username", Required)
	v.AddRule("Password", Required)
	v.AddRule("Email", Required, "邮箱不能为空")
	// 添加自定义邮箱格式校验规则
	v.AddRule("Email", EmailFormat)
	if !v.Validate(form) {
		fmt.Println("校验失败,错误信息:", v.GetErrors())
	}
}

优化规则参数传递

之前的规则实现中,部分规则需要额外参数(比如MinLength需要长度参数),我们可以优化校验器的AddRule方法,支持传递规则参数,让规则使用更灵活。

// 优化后的AddRule方法,支持传递规则参数
func (v *Validator) AddRuleWithParam(field string, rule Rule, param string, customMsg ...string) *Validator {
	if len(customMsg) > 0 {
		rule.Msg = customMsg[0]
	}
	// 把规则和参数绑定,执行校验时传递参数
	type ruleWithParam struct {
		rule  Rule
		param string
	}
	// 存储带参数的规则,这里可以扩展rules的结构,实际需要调整rules的类型定义
	// 简化示例,直接在校验时处理参数逻辑,此处省略完整扩展代码
	return v
}

通过以上实现,我们就完成了一个基础的Golang表单校验库,支持常用规则定义、规则复用、自定义规则扩展,能够满足大部分Web开发中的表单校验需求。开发者可以根据实际业务场景继续扩展更多预定义规则,比如数字范围校验、正则匹配校验等,让校验库的功能更完善。

Golang表单校验库输入校验规则规则复用修改时间:2026-07-21 14:27:43

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。