【C++/Lua联合开发】 (一) Lua基础知识
文章目录
- Lua 语言简介
- 1. Lua基础数据类型
- Nil
- boolean
- Number
- String
- 字符串处理
- 2. 条件判断和循环语句
- if语句
- while循环
- repeat语句
- for循环
- 3. 表
- 数组表
- 二维数组
- 哈希表
- 4. 函数
- 语法
- 函数类型的变量
- 重载
- 示例:同名函数覆盖
- 模拟重载(推荐方式)
Lua 语言简介
Lua 是一种轻量级、高效的脚本语言,由巴西里约热内卢天主教大学(PUC-Rio)于1993年开发。它的名字在葡萄牙语中意为"月亮"。
Lua 的主要特点:
- 轻量级: 核心库非常小巧,完整的解释器只有几百KB
- 高效: 执行速度在脚本语言中名列前茅,特别是使用 LuaJIT 时
- 可嵌入: 设计初衷就是作为嵌入式脚本语言
- 简洁语法: 语法简单清晰,易于学习
- 动态类型: 弱类型语言,灵活但需注意类型安全
- 垃圾回收: 自动内存管理
- 协程支持: 内置协程机制,便于实现复杂的控制流
1. Lua基础数据类型
- Nil
- Boolean
- Number
- String
Nil
nil
表示没有数据/未初始化的值, 全局变量设为nil
会交给垃圾回收
lua的nil与C++的nullptr对比:
特性 | nil | nullptr |
---|---|---|
类型 | 独立的数据类型 | 类型安全的指针字面量 |
表示对象 | 任何不存在或者未初始化的东西 | 仅表示空指针 |
内存管理 | 内存回收,将变量或者字段设为nil会帮助回收器释放内存 | 不参与内存管理 |
用途 | 更像是一个通用占位符 | 静态类型检查工具,防止空指针解引用错误,编译时就会判断 |
boolean
-
lua中所有值都可以作为条件
-
除了
false
和nil
,其他值都为真,0也为真
Number
-
Lua没有整数,都是用浮点数运算
-
对应c的
double
类型 -
tonumber
函数转换格式
String
-
tostring
转换格式 -
[[]]
多行字符串 -
“与c一样的转义 "
-
..
字符串拼接
字符串处理
-
string.len
-
string.sub(str, 3 ,5)
下标从1开始 -
查找:
local b,e = string.find(str, "HEAD")
支持正则 // b,e为起始和结束坐标number -
替换:
string.gsub(str, "HEAD", "TAIL")
支持正则
2. 条件判断和循环语句
if语句
if conditions thenthen part
elseif conditions then elseif part
else else part
end
while循环
- 示例
while condition do statements;
end
没有`continue`
break
推出循环
repeat语句
repeat statements
until conditions
local i = 0
repeat print("i=" .. i)i = i + 1
until(i > 10)
for循环
-
数值循环
for var=from,to,step do loop-part end
for var = 1, 5, 1 doprint("var=" .. var)
end
- 范型循环
for i,v in ipairs(a) do print(v)
end
- 示例
local days = {"Sunday", "Monday", "Tuesday", "Wednesday"}
for i, day in ipairs(days) doprint("Day " .. i .. ": " .. day)
end
3. 表
-
表的大小
table.getn(t1)
-
插入
table.insert(tab, pos, value)
不传
pos
相当于push_back
-
删除 t
able.remove(tab, pos)
,返回删除的值不传
pos
相当于pop_back
数组表
local tab1 = {"001", "002", "003"}
for i, v in ipairs(tab1) doprint("index: " .. i .. ", value: " .. v)
endprint("----- insert -----")
table.insert(tab1, 3, "002-2")
for i, v in ipairs(tab1) doprint("index: " .. i .. ", value: " .. v)
endprint("----- insert back-----")
table.insert(tab1, 4)
for i, v in ipairs(tab1) doprint("index: " .. i .. ", value: " .. v)
endprint("----- remove -----")
table.remove(tab1, 3)
for i, v in ipairs(tab1) doprint("index: " .. i .. ", value: " .. v)
endprint("----- remove back -----")
table.remove(tab1)
for i, v in ipairs(tab1) doprint("index: " .. i .. ", value: " .. v)
end
二维数组
local tab3 = {}
tab3[1] = {"apple", "banana", "cherry"}
tab3[2] = {"dog", "cat", "mouse"}for i = 1, #tab3 doprint("Table " .. i .. ":")for j = 1, #tab3[i] doprint(" " .. tab3[i][j])end
end
哈希表
local tab2 = {id=123, age=20}
tab2["name"] = "sgzed"
tab2["name"] = nil for k, v in pairs(tab2) doprint("k" .. " : " .. v)
end
在 table
构造器里 name = expr
这种简写要求 name
是合法的标识符(字母或下划线开头,后面跟字母/数字/下划线),不能以数字开头。因此写 local t = {1 = 123}
会报语法错误。
正确的写法有两种(等价或常用):
-- 数组形式(省略键,索引从 1 开始)
local t1 = {123, 30} -- 等同于 {[1]=123, [2]=30}-- 显式数字键(必须用方括号)
local t2 = {[1] = 123, [2] = 30}-- 如果想用字符串 "1" 作为键,需加引号或方括号
local t3 = {["1"] = 123} -- t3["1"] 有值,但 t3[1] 是 nil(不同键)
要点:
- 标识符形式(id = val)只能用合法标识符,不能以数字开头。
- 数字键必须用方括号
[n]
,或用省略键的数组语法。
4. 函数
语法
-
函数语法
function func_name(arguments-list) statements-list end
-
Lua参数
-
普通参数
function test(para1, para2) end
function test(p1, p2)if(p1 == nil) thenp1 = "default1"endif(p2 == nil) thenp2 = "default2"endprint(p1 .. " : " .. p2) endtest("hello")
-
-
可变参数
function each(...)local n = select("#", ...)for i = 1, n dolocal v = select(i, ...) -- 每次取第 i 个参数print(i, v)end endeach("x","y","z")
函数类型的变量
-- 方式1:点号
local input1 = {}
function input1.get(t)print("input received: " .. t)
end
input1.get("Hello, World!") -- 输出: input received: Hello, World!-- 方式2:冒号
local input2 = {}
function input2:get(t)print(self, t) -- self 是 input2
end
input2:get("Hello") -- 输出: table: 0x... Hello
要点:input
是 table
,get
是 table
的一个函数字段;点号(.)和冒号(:)在定义与调用时决定是否隐式传入 self
。
重载
Lua 不支持函数重载(overloading),即不能根据参数类型或数量定义多个同名函数(不像 C++ 或 Java)。函数是第一类值,可以赋值给变量。如果定义两个同名函数,后定义的会覆盖前面的,导致前面的不可用。
示例:同名函数覆盖
function add(a, b)return a + b
endfunction add(a, b, c) -- 覆盖上面的 addreturn a + b + c
endprint(add(1, 2)) -- 报错:add 函数期望 3 个参数,但只给了 2 个
print(add(1, 2, 3)) -- 输出: 6
模拟重载(推荐方式)
用一个函数检查参数数量或类型:
function add(...)local args = {...}local n = select("#", ...)if n == 2 thenreturn args[1] + args[2]elseif n == 3 thenreturn args[1] + args[2] + args[3]elseerror("Invalid number of arguments")end
endprint(add(1, 2)) -- 输出: 3
print(add(1, 2, 3)) -- 输出: 6
要点:Lua 强调灵活性,通过可变参数 (…) 和条件检查实现类似重载;避免同名覆盖,使用不同名称或 table 存储函数。