Lua 基本语法详解
1. 注释
-- 单行注释
--[[
多行注释
可以写很多行
--]]
---@class MyClass -- 注解注释(用于 IDE 类型提示)
2. 变量和数据类型
变量声明
local x = 10 -- 局部变量(推荐)
y = 20 -- 全局变量(不推荐)
local a, b, c = 1, 2, 3 -- 多重赋值
8种数据类型
local n = nil -- 空值
local b = true -- 布尔值:true/false
local num = 3.14 -- 数字(整数和浮点数)
local str = "hello" -- 字符串
local func = function() end -- 函数
local tbl = {} -- 表(table)
local thread = coroutine.create(function() end) -- 协程
local ud = nil -- userdata(C数据)
-- 检查类型
print(type(n)) -- nil
print(type(b)) -- boolean
print(type(num)) -- number
3. 字符串
local s1 = "单引号"
local s2 = '双引号'
local s3 = [[
多行字符串
保留换行和空格
]]
-- 字符串连接
local result = "Hello" .. " " .. "World"
-- 字符串长度
print(#"Hello") -- 5
-- 常用字符串函数
string.upper("hello") -- "HELLO"
string.lower("HELLO") -- "hello"
string.sub("hello", 1, 2) -- "he"
string.format("%d + %d = %d", 1, 2, 3) -- "1 + 2 = 3"
string.find("hello", "ll") -- 3, 4
string.gsub("hello", "l", "L") -- "heLLo"
4. 运算符
算术运算符
local a = 10 + 5 -- 加法:15
local b = 10 - 5 -- 减法:5
local c = 10 * 5 -- 乘法:50
local d = 10 / 5 -- 除法:2.0
local e = 10 % 3 -- 取模:1
local f = 10 ^ 2 -- 幂运算:100
local g = -10 -- 负号
关系运算符
10 == 10 -- 等于:true
10 ~= 5 -- 不等于:true
10 > 5 -- 大于:true
10 < 5 -- 小于:false
10 >= 10 -- 大于等于:true
10 <= 5 -- 小于等于:false
逻辑运算符
true and false -- 与:false
true or false -- 或:true
not true -- 非:false
-- 短路求值
local x = nil
local y = x or 10 -- y = 10(x为nil时使用默认值)
local z = x and x.value -- z = nil(避免访问nil)
其他运算符
#"hello" -- 长度运算符:5
#tbl -- 表的长度
"ab".."cd" -- 字符串连接:abcd
5. 控制结构
if 语句
local score = 85
if score >= 90 then
print("优秀")
elseif score >= 60 then
print("及格")
else
print("不及格")
end
-- 三元运算符的替代
local result = (score >= 60) and "及格" or "不及格"
while 循环
local i = 1
while i <= 5 do
print(i)
i = i + 1
end
repeat-until 循环
local i = 1
repeat
print(i)
i = i + 1
until i > 5 -- 注意:条件为真时退出
for 循环
-- 数值for循环
for i = 1, 10 do
print(i) -- 1到10
end
for i = 1, 10, 2 do
print(i) -- 1, 3, 5, 7, 9(步长为2)
end
for i = 10, 1, -1 do
print(i) -- 10到1(倒序)
end
-- 泛型for循环(遍历表)
local tbl = {10, 20, 30}
for index, value in ipairs(tbl) do
print(index, value)
end
local dict = {name="张三", age=20}
for key, value in pairs(dict) do
print(key, value)
end
break 和 goto
for i = 1, 10 do
if i == 5 then
break -- 跳出循环
end
print(i)
end
-- goto(Lua 5.2+)
::retry::
print("尝试连接...")
if not connected then
goto retry
end
6. 函数
函数定义
-- 基本定义
function add(a, b)
return a + b
end
-- 匿名函数
local multiply = function(a, b)
return a * b
end
-- 多返回值
function getMinMax(a, b)
if a < b then
return a, b
else
return b, a
end
end
local min, max = getMinMax(10, 5) -- min=5, max=10
可变参数
function sum(...)
local args = {...} -- 打包成表
local total = 0
for _, v in ipairs(args) do
total = total + v
end
return total
end
print(sum(1, 2, 3, 4, 5)) -- 15
闭包
function makeCounter()
local count = 0
return function()
count = count + 1
return count
end
end
local counter = makeCounter()
print(counter()) -- 1
print(counter()) -- 2
7. 表(Table)
创建表
local arr = {10, 20, 30} -- 数组(索引从1开始)
local dict = {name="张三", age=20} -- 字典
local mixed = {10, 20, name="张三"} -- 混合
访问表
-- 数组访问
print(arr[1]) -- 10
-- 字典访问
print(dict["name"]) -- 张三
print(dict.name) -- 张三(语法糖)
-- 添加元素
arr[4] = 40
dict.gender = "男"
表操作
-- 插入
table.insert(arr, 40) -- 末尾插入
table.insert(arr, 1, 5) -- 指定位置插入
-- 删除
table.remove(arr) -- 删除最后一个
table.remove(arr, 1) -- 删除指定位置
-- 连接
local str = table.concat(arr, ", ") -- "10, 20, 30"
-- 排序
table.sort(arr) -- 升序
table.sort(arr, function(a, b) return a > b end) -- 降序
-- 长度
print(#arr) -- 数组部分的长度
遍历表
local tbl = {10, 20, 30, name="张三"}
-- ipairs:只遍历数组部分(连续整数索引)
for i, v in ipairs(tbl) do
print(i, v) -- 1,10 2,20 3,30
end
-- pairs:遍历所有键值对
for k, v in pairs(tbl) do
print(k, v) -- 1,10 2,20 3,30 name,张三
end
8. 面向对象(基于表和元表)
简单类
-- 定义类
local Person = {}
Person.__index = Person
-- 构造函数
function Person.new(name, age)
local self = setmetatable({}, Person)
self.name = name
self.age = age
return self
end
-- 方法
function Person:sayHi()
print("Hi, I'm " .. self.name)
end
-- 使用
local p = Person.new("张三", 20)
p:sayHi() -- Hi, I'm 张三
继承
local Student = {}
Student.__index = Student
setmetatable(Student, {__index = Person})
function Student.new(name, age, school)
local self = Person.new(name, age)
setmetatable(self, Student)
self.school = school
return self
end
function Student:study()
print(self.name .. " is studying at " .. self.school)
end
local tbl = {value = 10}
local mt = {
-- 算术运算
__add = function(t1, t2) return t1.value + t2.value end,
__sub = function(t1, t2) return t1.value - t2.value end,
-- 访问不存在的键
__index = function(t, key)
return "Key not found: " .. key
end,
-- 设置键值
__newindex = function(t, key, value)
rawset(t, key, value * 2)
end,
-- 转字符串
__tostring = function(t)
return "Value: " .. t.value
end,
-- 调用表
__call = function(t, x)
return t.value + x
end
}
setmetatable(tbl, mt)
print(tbl.abc) -- Key not found: abc
tbl.new = 5 -- 实际存储 10
print(tbl(5)) -- 15
10. 模块
创建模块
-- mymodule.lua
local M = {}
function M.add(a, b)
return a + b
end
function M.sub(a, b)
return a - b
end
return M
使用模块
local mymodule = require("mymodule")
print(mymodule.add(10, 5)) -- 15
11. 错误处理
-- pcall(保护调用)
local success, result = pcall(function()
return 10 / 0
end)
if success then
print("结果:", result)
else
print("错误:", result)
end
-- xpcall(带错误处理函数)
local function errorHandler(err)
return "错误: " .. tostring(err)
end
xpcall(function()
error("出错了")
end, errorHandler)
-- assert(断言)
local x = nil
assert(x, "x 不能为 nil") -- 如果x为nil则抛出错误
12. 协程(Coroutine)
local co = coroutine.create(function()
for i = 1, 3 do
print("协程:", i)
coroutine.yield() -- 暂停
end
end)
coroutine.resume(co) -- 协程: 1
coroutine.resume(co) -- 协程: 2
coroutine.resume(co) -- 协程: 3
print(coroutine.status(co)) -- dead
13. 常用全局函数
-- 类型相关
type(x) -- 返回类型
tonumber("123") -- 转数字:123
tostring(123) -- 转字符串:"123"
-- 输出
print("Hello") -- 打印
-- 数学
math.abs(-10) -- 绝对值:10
math.ceil(3.2) -- 向上取整:4
math.floor(3.8) -- 向下取整:3
math.max(1,2,3) -- 最大值:3
math.min(1,2,3) -- 最小值:1
math.random() -- 随机数 [0,1)
math.random(10) -- 随机整数 [1,10]
math.pi -- π
-- 操作系统
os.time() -- 当前时间戳
os.date() -- 格式化时间
os.clock() -- CPU时间
14. 重要注意事项
索引从1开始
local arr = {10, 20, 30}
print(arr[1]) -- 10(不是arr[0])
nil 和 false 的区别
local x = nil
local y = false
if not x then print("x is falsy") end -- 输出
if not y then print("y is falsy") end -- 输出
-- 但在表中:
local tbl = {a = nil, b = false}
print(tbl.a) -- nil(键不存在)
print(tbl.b) -- false(键存在,值为false)
局部变量优先
local x = 10
function test()
local x = 20 -- 局部变量,不影响外部
print(x) -- 20
end
test()
print(x) -- 10
冒号和点号
-- 冒号会自动传递self
obj:method(arg) -- 等价于 obj.method(obj, arg)
-- 点号需要手动传递
obj.method(obj, arg)