Lua 基本数据类型
Lua是一种动态类型语言,变量没有类型,值才有类型。Lua共有8种基本数据类型:
- nil(空值)
- boolean(布尔值)
- number(数值)
- string(字符串)
- function(函数)
- userdata(用户数据)
- thread(协程)
- table(表)
8种基本数据类型
1. nil(空值)
lua
local a = nil
print(a) -- 输出: nil
print(type(a)) -- 输出: nil
-- nil表示不存在的值或变量未初始化
local b
print(b) -- 输出: nil (变量声明但未赋值)
2. boolean(布尔值)
lua
local t = true
local f = false
-- 重要细节:在Lua中,只有false和nil表示逻辑假
-- 其他所有值(包括0和空字符串)都表示逻辑真
if 0 then
print("0 在Lua中为真") -- 会执行
end
if "" then
print("空字符串在Lua中为真") -- 会执行
end
if false then
print("false为假,不会执行")
end
if nil then
print("nil为假,不会执行")
end
3. number(数值)
lua
-- Lua 5.3+ 支持整数和浮点数,5.2及之前只有浮点数
local int_num = 42
local float_num = 3.14
local sci_num = 2e10 -- 科学计数法
local hex_num = 0xFF -- 十六进制
print(type(int_num)) -- 输出: number
print(type(float_num)) -- 输出: number
-- 重要细节:浮点数比较问题
local a = 0.1 + 0.2
local b = 0.3
print(a == b) -- 输出: false (由于浮点数精度问题)
-- 正确的浮点数比较方法
local epsilon = 1e-10 -- 定义一个极小的误差范围
function float_equal(x, y)
return math.abs(x - y) < epsilon
end
print(float_equal(a, b)) -- 输出: true
-- 使用math.abs比较示例
local x = 1/3
local y = 0.33333333333333
if math.abs(x - y) < 0.000001 then
print("x和y在误差范围内相等")
end
4. string(字符串)
lua
-- 三种表示方式
local str1 = "双引号字符串"
local str2 = '单引号字符串'
local str3 = [[
多行字符串
可以包含换行
和"各种引号"
]]
-- 字符串连接
local name = "Lua"
local greeting = "Hello, " .. name .. "!"
print(greeting) -- 输出: Hello, Lua!
-- 字符串长度
local s = "hello"
print(#s) -- 输出: 5 (长度操作符)
-- 数字与字符串的自动转换(在算术运算中)
print("10" + 5) -- 输出: 15 (字符串转换为数字)
print(10 .. 20) -- 输出: 1020 (数字转换为字符串,注意空格: 10 .. 20)
-- 显式转换
local num = tonumber("123") -- 字符串转数字
local str = tostring(123) -- 数字转字符串
5. table(表)
lua
-- Lua中唯一的数据结构,可作数组、字典、对象等
local empty_table = {}
local array = {1, 2, 3, 4, 5} -- 数组
local dict = {name = "Lua", version = 5.4} -- 字典
local mixed = {1, "two", three = 3} -- 混合
-- 访问元素
print(array[1]) -- 输出: 1 (注意:Lua数组索引从1开始)
print(dict["name"]) -- 输出: Lua
print(dict.name) -- 输出: Lua (语法糖)
-- 获取长度(针对数组部分)
print(#array) -- 输出: 5
6. function(函数)
lua
-- 函数是一等公民,可以存储在变量中
local function add(a, b)
return a + b
end
local multiply = function(a, b)
return a * b
end
-- 高阶函数:函数作为参数
function apply(func, x, y)
return func(x, y)
end
print(apply(add, 3, 4)) -- 输出: 7
7. userdata(用户数据)
lua
-- 表示C语言数据,用于Lua与C的交互
-- 通常由C扩展库创建,在纯Lua中很少直接创建
8. thread(协程)
lua
-- 表示独立的执行线程(协程)
local co = coroutine.create(function()
print("协程执行")
end)
print(type(co)) -- 输出: thread
类型检查与转换
lua
-- 类型检查函数 type()
print(type("hello")) -- string
print(type(123)) -- number
print(type(true)) -- boolean
print(type(nil)) -- nil
print(type({})) -- table
print(type(print)) -- function
-- 类型转换函数
local num = tonumber("123") -- 转换为数字,失败返回nil
local str = tostring(123) -- 转换为字符串
local bool = not not value -- 转换为布尔值(双非技巧)
-- 检查特定类型
function is_number(value)
return type(value) == "number"
end
function is_string(value)
return type(value) == "string"
end
注意事项
1. 关于nil
lua
-- 给变量赋nil等同于删除变量
local t = {x = 10, y = 20}
t.x = nil -- 删除键x
-- 判断变量是否存在
if some_var == nil then
print("变量不存在或值为nil")
end
2. 布尔运算的短路特性
lua
local a = nil
local b = "default"
-- 使用or提供默认值
local value = a or b
print(value) -- 输出: default
-- 使用and确保条件满足
function safe_divide(a, b)
b = b or 1 -- 默认分母为1
return a / b
end
3. 浮点数比较
lua
-- 定义比较函数
function float_eq(a, b, epsilon)
epsilon = epsilon or 1e-10
return math.abs(a - b) < epsilon
end
function float_lt(a, b, epsilon) -- less than
epsilon = epsilon or 1e-10
return b - a > epsilon
end
function float_le(a, b, epsilon) -- less than or equal
epsilon = epsilon or 1e-10
return a - b <= epsilon
end
4. 类型判断技巧
lua
-- 判断是否为table且不为空
function is_table(t)
return type(t) == "table"
end
function is_empty_table(t)
return type(t) == "table" and next(t) == nil
end
-- 判断是否为数组(连续整数键)
function is_array(t)
if type(t) ~= "table" then return false end
local i = 0
for _ in pairs(t) do
i = i + 1
if t[i] == nil then return false end
end
return true
end
总结
- Lua有8种基本数据类型,使用
type()函数获取类型 - 只有false和nil在条件判断中为假,其他所有值都为真
- 浮点数比较需要特别注意精度问题,应使用误差范围比较而非直接相等比较
- 字符串和数字在必要时会自动转换,但最好显式转换以提高代码清晰度
- table是Lua的核心数据结构,灵活但需要理解其工作原理
- 合理利用短路逻辑(and/or)可以写出更简洁的代码