参数校验 Lua API
概述
lvalidate 是一个 Lua 参数校验库,提供参数的类型和范围验证功能。
模块加载
local lvalidate = require('lvalidate')
主要特性
- 整数校验:
check_integer验证整数类型及范围,区分整值与浮点数 - 字符串长度校验:
lens和len_or_none检查字符串长度边界 - 数值范围校验:
ranges和range_or_none验证数值(含浮点数)范围 - 正则匹配:
regex和regex_or_none使用标准正则表达式校验字符串格式 - JSON 合法性:
Json快速验证字符串是否为合法 JSON - 可选的 nil 穿透:
_or_none变体允许 nil 值直接通过,简化可选参数校验 - 错误消息格式化:
need_convert参数控制错误消息格式,适配不同日志输出场景
函数
check_integer
验证一个值是否为整数类型,并且是否在指定的范围内。
语法
lvalidate.check_integer(name, val, min, max, need_convert)
参数
name(string) - 属性名称,用于错误消息中标识属性val(number) - 要验证的值min(number) - 允许的最小值(包含)max(number) - 允许的最大值(包含)need_convert(boolean) - 是否在错误消息中使用转换格式true- 错误消息中的属性名和值会添加%前缀(如%Prop1和%Prop1:150)false- 使用原始格式(如Prop1和150)
返回值
- 无返回值。如果验证通过,函数正常返回;如果验证失败,会抛出 Lua 错误。
异常
函数在以下情况下会抛出 Lua 错误:
-
类型错误 (
PropertyValueTypeError):val不是数字类型val是浮点数但有小数部分(如3.14、5.5)val是 NaN(Not a Number)
-
范围错误 (
PropertyValueOutOfRange):val小于min或大于maxmin或max不是数字类型
验证规则
-
类型检查:
val必须是数字类型(LUA_TNUMBER)- 如果
val是浮点数,必须没有小数部分(即必须是整数值) - 例如:
42✓、42.0✓、3.14✗、5.5✗
-
范围检查:
val必须在[min, max]范围内(包含边界)min和max必须是数字类型- 例如:
val=50, min=0, max=100✓、val=150, min=0, max=100✗
-
边界值:
- 边界值(
min和max)是包含的 - 例如:
val=0, min=0, max=100✓、val=100, min=0, max=100✓
- 边界值(
错误消息格式
类型错误:
PropertyValueTypeError: The value '<val>' for the property <name> is of a different type than the property can accept.
范围错误:
PropertyValueOutOfRange: The value '<val>' for the property <name> is not in the supported range of acceptable values.
当 need_convert 为 true 时:
- 属性名格式:
%<name>(如%Prop1) - 值格式:
%<name>:<val>(如%Prop1:150)
示例
基本用法
local lvalidate = require('lvalidate')
-- 验证有效整数
lvalidate.check_integer("Prop1", 42, 0, 100, false)
-- 成功,无返回值
-- 验证边界值
lvalidate.check_integer("Prop1", 0, 0, 100, false) -- 最小值边界
lvalidate.check_integer("Prop1", 100, 0, 100, false) -- 最大值边界
错误处理
local lvalidate = require('lvalidate')
-- 捕获类型错误
local success, err = pcall(lvalidate.check_integer, "Prop1", 3.14, 0, 100, false)
if not success then
print("类型错误:", err)
-- 输出: PropertyValueTypeError: The value '3.14' for the property Prop1 ...
end
-- 捕获范围错误
local success, err = pcall(lvalidate.check_integer, "Prop1", 150, 0, 100, false)
if not success then
print("范围错误:", err)
-- 输出: PropertyValueOutOfRange: The value '150' for the property Prop1 ...
end
使用 need_convert
local lvalidate = require('lvalidate')
-- need_convert = false(默认格式)
local success, err = pcall(lvalidate.check_integer, "Prop1", 150, 0, 100, false)
-- 错误消息: PropertyValueOutOfRange: The value '150' for the property Prop1 ...
-- need_convert = true(转换格式)
local success, err = pcall(lvalidate.check_integer, "Prop1", 150, 0, 100, true)
-- 错误消息: PropertyValueOutOfRange: The value '%Prop1:150' for the property %Prop1 ...
负数和跨零范围
local lvalidate = require('lvalidate')
-- 负数范围
lvalidate.check_integer("Temperature", -5, -10, 0, false) -- ✓ 通过
-- 跨零范围
lvalidate.check_integer("Offset", 0, -10, 10, false) -- ✓ 通过
lvalidate.check_integer("Offset", -5, -10, 10, false) -- ✓ 通过
lvalidate.check_integer("Offset", 5, -10, 10, false) -- ✓ 通过
相等边界
local lvalidate = require('lvalidate')
-- min == max == val
lvalidate.check_integer("FixedValue", 5, 5, 5, false) -- ✓ 通过
lens
验证字符串长度是否在指定的范围内。
语法
lvalidate.lens(name, val, min, max, need_convert)
参数
name(string) - 属性名称,用于错误消息中标识属性val(string) - 要验证的字符串min(number) - 允许的最小长度(包含)max(number) - 允许的最大长度(包含)need_convert(boolean) - 是否在错误消息中使用转换格式true- 错误消息中的属性名和值会添加%前缀(如%Prop1和%Prop1:abc)false- 使用原始格式(如Prop1和abc)
返回值
- 无返回值。如果验证通过,函数正常返回;如果验证失败,会抛出 Lua 错误。
异常
函数在以下情况下会抛出 Lua 错误:
-
类型错误 (
PropertyValueTypeError):val不是字符串类型
-
长度小于下限 (
StringValueTooShort):val长度小于min
-
长度大于上限 (
StringValueTooLong):val长度大于max
len_or_none
验证字符串长度是否在指定的范围内,允许入参值为 nil。
语法
lvalidate.len_or_none(name, val, min, max, need_convert)
参数
name(string) - 属性名称,用于错误消息中标识属性val(string | nil) - 要验证的字符串;为nil时跳过检查min(number) - 允许的最小长度(包含)max(number) - 允许的最大长度(包含)need_convert(boolean) - 是否在错误消息中使用转换格式true- 错误消息中的属性名和值会添加%前缀(如%Prop1和%Prop1:abc)false- 使用原始格式(如Prop1和abc)
返回值
- 无返回值。如果验证通过,函数正常返回;如果验证失败,会抛出 Lua 错误。
行为说明
- 当
val == nil时,直接返回,不抛出错误 - 当
val ~= nil时,行为与lens相同
异常
函数在以下情况下会抛出 Lua 错误:
-
类型错误 (
PropertyValueTypeError):val不是nil,并且不是字符串类型
-
长度小于下限 (
StringValueTooShort):val长度小于min
-
长度大于上限 (
StringValueTooLong):val长度大于max
ranges
验证一个数值是否在指定的范围内(允许浮点数)。
语法
lvalidate.ranges(name, val, min, max, need_convert)
参数
name(string) - 属性名称,用于错误消息中标识属性val(number) - 要验证的值(整数或浮点数)min(number) - 允许的最小值(包含)max(number) - 允许的最大值(包含)need_convert(boolean) - 是否在错误消息中使用转换格式true- 错误消息中的属性名和值会添加%前缀(如%Prop1和%Prop1:1.23)false- 使用原始格式(如Prop1和1.23)
返回值
- 无返回值。如果验证通过,函数正常返回;如果验证失败,会抛出 Lua 错误。
行为说明
val必须是 Lua 数字类型val必须在[min, max]范围内(包含边界)min和max必须是数字类型,否则会抛出错误
异常
函数在以下情况下会抛出 Lua 错误:
-
类型错误 (
PropertyValueTypeError):val不是数字类型
-
范围错误 (
PropertyValueOutOfRange):val小于min或大于max
range_or_none
验证一个数值是否在指定的范围内,允许入参为 nil(此时不做范围检查)。
语法
lvalidate.range_or_none(name, val, min, max, need_convert)
参数
name(string) - 属性名称,用于错误消息中标识属性val(number | nil) - 要验证的值;为nil时跳过检查min(number) - 允许的最小值(包含)max(number) - 允许的最大值(包含)need_convert(boolean) - 是否在错误消息中使用转换格式
返回值
- 无返回值。如果验证通过,函数正常返回;如果验证失败,会抛出 Lua 错误。
行为说明
- 当
val == nil时,直接返回,不抛出错误 - 当
val ~= nil时,行为同ranges
异常
函数在以下情况下会抛出 Lua 错误:
-
类型错误 (
PropertyValueTypeError):val不是nil,并且不是数字类型
-
范围错误 (
PropertyValueOutOfRange):val不是nil,并且小于min或大于max
regex
验证字符串是否匹配指定的标准正则表达式。
语法
lvalidate.regex(name, val, pattern, need_convert)
参数
name(string) - 属性名称,用于错误消息中标识属性val(string) - 要验证的字符串pattern(string) - 标准正则表达式need_convert(boolean) - 是否在错误消息中使用转换格式
返回值
- 无返回值。如果验证通过,函数正常返回;如果验证失败,会抛出 Lua 错误。
行为说明
- 当
val不是字符串时,抛出类型相关错误 - 当
val不匹配给定的pattern时,抛出匹配失败的错误
异常
函数在以下情况下会抛出 Lua 错误:
-
类型错误 (
PropertyValueTypeError):val不是字符串类型
-
正则不匹配 (
PropertyValueFormatError):val不匹配给定的pattern
regex_or_none
验证字符串是否匹配指定的标准正则表达式,允许入参为 nil。
语法
lvalidate.regex_or_none(name, val, pattern, need_convert)
参数
name(string) - 属性名称,用于错误消息中标识属性val(string | nil) - 要验证的字符串;为nil时跳过检查pattern(string) - 标准正则表达式need_convert(boolean) - 是否在错误消息中使用转换格式
返回值
- 无返回值。如果验证通过,函数正常返回;如果验证失败,会抛出 Lua 错误。
行为说明
- 当
val == nil时,直接返回,不抛出错误 - 当
val ~= nil时,行为同regex
异常
函数在以下情况下会抛出 Lua 错误:
-
类型错误 (
PropertyValueTypeError):val不是nil,并且不是字符串类型
-
正则不匹配 (
PropertyValueFormatError):val不是nil,并且不匹配给定的pattern
Json
验证一个字符串是否是合法的 JSON 文本。
语法
lvalidate.Json(val)
参数
val(string) - 要验证的字符串
返回值
- 无返回值。如果验证通过,函数正常返回;如果验证失败,会抛出 Lua 错误。
行为说明
- 当
val不是字符串时,抛出MalformedJSON错误 - 使用 JSON 解析库对
val进行反序列化 - 如果反序列化失败(不是合法的 JSON),抛出
MalformedJSON错误
异常
函数在以下情况下会抛出 Lua 错误:
- 不合法JSON (
MalformedJSON):val不是字符串类型,或val不是合法的 JSON 字符串
最佳实践
✅ 用 pcall 统一捕获所有校验错误
lvalidate 函数在失败时抛出 Lua 错误,统一使用 pcall 包装,避免校验失败中断业务流程:
-- ✅ 统一捕获校验错误
local ok, err = pcall(lvalidate.check_integer, "Port", port, 1, 65535, false)
if not ok then
log:error("参数校验失败: ${err}", "err", tostring(err))
return nil, err
end
✅ 可选参数使用 _or_none 变体
当参数允许为空时,直接使用 _or_none 函数,避免手写 nil 判断:
-- ✅ 用 len_or_none 处理可选字符串
lvalidate.len_or_none("Description", desc, 0, 256, false)
-- desc 为 nil 时自动跳过,无需额外 if
❌ 不要在校验循环中逐条 catch 来收集错误
-- ❌ 逐条捕获效率低且信息不完整
for _, rule in ipairs(rules) do
local ok = pcall(lvalidate.check_integer, rule.name, val, rule.min, rule.max, false)
if not ok then return false end
end
-- ✅ 批量校验,先收集再报错
local errors = {}
for _, rule in ipairs(rules) do
local ok, err = pcall(lvalidate.check_integer, rule.name, val, rule.min, rule.max, false)
if not ok then table.insert(errors, tostring(err)) end
end
if #errors > 0 then
log:error("批量校验失败: ${count} 项", "count", #errors)
end
❌ 避免对非 JSON 字符串使用 Json 函数
Json 内部会进行完整的 JSON 反序列化,开销较大。仅在确实需要验证 JSON 时才使用:
-- ❌ 对普通字符串不该用 Json
lvalidate.Json("hello world") -- 抛异常且无必要
-- ✅ Json 仅用于需要确认 JSON 格式的场景
lvalidate.Json('{"key":"value"}')