【C++/Lua联合开发】 (一) Lua基础知识

文章目录

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中所有值都可以作为条件

  • 除了falsenil,其他值都为真,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语句

lua 复制代码
if conditions then
    then part
elseif conditions then 
    elseif part 
else 
    else part 
end 

while循环

  • 示例
lua 复制代码
while condition do 
    statements;
end 
复制代码
没有`continue`
  • break推出循环

repeat语句

lua 复制代码
repeat 
    statements 
until conditions
lua 复制代码
local i = 0 
repeat 
    print("i=" .. i)
    i = i + 1
until(i > 10)

for循环

  • 数值循环

    lua 复制代码
    for var=from,to,step do 
        loop-part 
    end 
lua 复制代码
for var = 1, 5, 1 do
    print("var=" .. var)
end
  • 范型循环
lua 复制代码
for i,v in ipairs(a) do 
    print(v)
end
  1. 示例
lua 复制代码
local days = {"Sunday", "Monday", "Tuesday", "Wednesday"}
for i, day in ipairs(days) do
    print("Day " .. i .. ": " .. day)
end

3. 表

  • 表的大小 table.getn(t1)

  • 插入 table.insert(tab, pos, value)

    不传pos相当于push_back

  • 删除 table.remove(tab, pos),返回删除的值

    不传pos相当于 pop_back

数组表

lua 复制代码
local tab1 = {"001", "002", "003"}
for i, v in ipairs(tab1) do
    print("index: " .. i .. ", value: " .. v)
end

print("----- insert -----")
table.insert(tab1, 3, "002-2")
for i, v in ipairs(tab1) do
    print("index: " .. i .. ", value: " .. v)
end

print("----- insert back-----")
table.insert(tab1, 4) 
for i, v in ipairs(tab1) do
    print("index: " .. i .. ", value: " .. v)
end

print("----- remove -----")
table.remove(tab1, 3)
for i, v in ipairs(tab1) do
    print("index: " .. i .. ", value: " .. v)
end

print("----- remove back -----")
table.remove(tab1)
for i, v in ipairs(tab1) do
    print("index: " .. i .. ", value: " .. v)
end 

二维数组

lua 复制代码
local tab3 = {}
tab3[1] = {"apple", "banana", "cherry"}
tab3[2] = {"dog", "cat", "mouse"}

for i = 1, #tab3 do
    print("Table " .. i .. ":")
    for j = 1, #tab3[i] do
        print("  " .. tab3[i][j])
    end
end

哈希表

lua 复制代码
local tab2 = {id=123, age=20}
tab2["name"] = "sgzed"
tab2["name"] = nil 

for k, v in pairs(tab2) do
    print("k" .. " : " .. v)
end 

table 构造器里 name = expr 这种简写要求 name 是合法的标识符(字母或下划线开头,后面跟字母/数字/下划线),不能以数字开头。因此写 local t = {1 = 123} 会报语法错误。

正确的写法有两种(等价或常用):

lua 复制代码
-- 数组形式(省略键,索引从 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. 函数

语法

  • 函数语法

    lua 复制代码
    function func_name(arguments-list)  
          statements-list
    end
  • Lua参数

    • 普通参数

      lua 复制代码
      function test(para1, para2)
      end
      lua 复制代码
      function test(p1, p2)
          if(p1 == nil) then
              p1 = "default1"
          end
      
          if(p2 == nil) then
              p2 = "default2"
          end
      
          print(p1 .. " : " .. p2)
      end
      
      test("hello")
  • 可变参数

    lua 复制代码
    function each(...)
        local n = select("#", ...)
        for i = 1, n do
            local v = select(i, ...)   -- 每次取第 i 个参数
            print(i, v)
        end
    end
    
    each("x","y","z")

函数类型的变量

lua 复制代码
-- 方式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

要点:inputtablegettable 的一个函数字段;点号(.)和冒号(:)在定义与调用时决定是否隐式传入 self

重载

Lua 不支持函数重载(overloading),即不能根据参数类型或数量定义多个同名函数(不像 C++ 或 Java)。函数是第一类值,可以赋值给变量。如果定义两个同名函数,后定义的会覆盖前面的,导致前面的不可用。

示例:同名函数覆盖
lua 复制代码
function add(a, b)
    return a + b
end

function add(a, b, c)  -- 覆盖上面的 add
    return a + b + c
end

print(add(1, 2))      -- 报错:add 函数期望 3 个参数,但只给了 2 个
print(add(1, 2, 3))   -- 输出: 6
模拟重载(推荐方式)

用一个函数检查参数数量或类型:

lua 复制代码
function add(...)
    local args = {...}
    local n = select("#", ...)
    if n == 2 then
        return args[1] + args[2]
    elseif n == 3 then
        return args[1] + args[2] + args[3]
    else
        error("Invalid number of arguments")
    end
end

print(add(1, 2))      -- 输出: 3
print(add(1, 2, 3))   -- 输出: 6

要点:Lua 强调灵活性,通过可变参数 (...) 和条件检查实现类似重载;避免同名覆盖,使用不同名称或 table 存储函数。

相关推荐
墨尘笔尖5 小时前
使用子进程实现 C++ 与 Python 交互式控制台
c++·windows·python
喜欢吃燃面5 小时前
算法中的链表结构
开发语言·c++·学习·算法
十五年专注C++开发5 小时前
Fruit框架:C++依赖注入解决方案
开发语言·c++·依赖注入·fruit框架
Juan_20125 小时前
P1041题解
c++·算法·题解·搜索
冷崖5 小时前
const 与 constexpr
c++·学习
EasyCVR6 小时前
视频汇聚平台EasyCVR在智慧工地无网线无电线监控现场视频解决方案
音视频
枫叶丹46 小时前
【Qt开发】多元素类控件(三)-> QTreeWidget
开发语言·数据库·c++·qt
hansang_IR6 小时前
【题解】P2217 [HAOI2007] 分割矩阵 [记忆化搜索]
c++·数学·算法·记忆化搜索·深搜
EasyGBS6 小时前
EasyGBS如何在平安乡村搭建无线视频联网监控系统?
音视频