Lua 学习笔记

最近做仪器软件开发,需要一种脚本语言做对外接口,Lua的解析器小巧、语法简单、方便和C绑定,所以选择了Lua,记录学习笔记如下:

一、变量与类型

变量声明与赋值

  • 直接赋值即可声明变量,无需显式声明类型
  • 使用 local 声明局部变量,仅在当前作用域(如文件、函数、代码块)内有效
  • 未声明的变量默认值为 nil
  • 支持同时给多个变量赋值,例如:x, y, z = 1, 2, 3

Number(数值类型)

  • Lua 中所有数值均为 number 类型(内部可能为整数或浮点数,自动转换)

  • 支持多种表示方式:

    lua 复制代码
    a = 42           -- 十进制
    b = 0xFF         -- 十六进制
    c = 3.14e-2      -- 科学计数法
  • 支持常见算术运算(+-*/%)及位运算(>><<&|~

String(字符串类型)

  • 用双引号 " 或单引号 ' 表示,如:"hello"'world'

  • 使用 [[ ... ]] 包裹的字符串不解析转义字符,适合多行文本

  • 字符串连接使用 .. 运算符

  • 常用字符串函数:

    lua 复制代码
    s = "Lua"
    print(#s)                    -- 获取长度:3
    print(string.format("%s %d", "Lua", 5))  -- 格式化输出
    print(string.sub(s, 2, 3))   -- 取子串:"ua"
    print(string.char(65, 66))   -- ASCII 转字符:"AB"
    print(string.byte("A"))      -- 字符转 ASCII:65

类型转换

  • tostring(number):将数字转为字符串

  • tonumber(string):将字符串转为数字,失败则返回 nil

    lua 复制代码
    print(tostring(123))        -- "123"
    print(tonumber("456"))      -- 456
    print(tonumber("abc"))      -- nil

二、Table(表)

基本特性

  • Table 是 Lua 中唯一的数据结构,可当作数组、字典、对象使用
  • 可存储任意类型值(数字、字符串、函数、甚至其他表)
  • 数字下标从 1 开始
  • 使用 #table 获取数组部分的长度(不包含字符串键值)

数组式用法

lua 复制代码
arr = {1, "hello", {x=1}, function() print("func") end}
table.insert(arr, "new")      -- 尾部插入
table.remove(arr, 2)          -- 移除第2个元素
print(#arr)                   -- 获取长度
print(arr[1])                 -- 访问第一个元素

字典式用法(字符串下标)

lua 复制代码
dict = {
    name = "Lua",
    version = 5.4,
    say = function() print("Hi") end
}
dict["extra"] = "some value"   -- 等价于 dict.extra = "some value"
print(dict.name)               -- "Lua"
dict.say()                     -- 调用函数,输出 "Hi"

遍历 Table

lua 复制代码
for k, v in pairs(dict) do
    print(k, v)
end
-- 仅遍历数组部分(连续数字下标)
for i, v in ipairs(arr) do
    print(i, v)
end

三、Function(函数)

定义函数

两种等价方式:

lua 复制代码
-- 方式一:直接定义
function add(a, b)
    return a + b
end

-- 方式二:匿名函数赋值
add = function(a, b)
    return a + b
end

函数特性

  • 可以返回多个值
  • 调用时传入参数少于形参,缺少的参数为 nil
  • 调用时传入参数多于形参,多余参数被忽略
  • 无显式 return 时,返回 nil
lua 复制代码
function multiReturn()
    return 1, "two", true
end
local a, b, c = multiReturn()
print(a, b, c)  -- 1    two    true

四、布尔类型与逻辑运算

布尔值

  • 只有 truefalse 两个值
  • 注意:在条件判断中,只有 falsenil 视为"假",0 和空字符串均为真

逻辑运算符

  • and:逻辑与
  • or:逻辑或
  • not:逻辑非
  • 不等于使用 ~= 表示

三元运算模拟

Lua 中没有 ? : 三元运算符,但可用 andor 模拟:

lua 复制代码
local result = (condition) and "yes" or "no"
-- 相当于 condition ? "yes" : "no"

示例:

lua 复制代码
print(0 and "yes" or "no")   -- "yes"(因为 0 为真)
print(nil and "yes" or "no") -- "no"

五、流程控制

条件判断

lua 复制代码
if score >= 90 then
    print("优秀")
elseif score >= 60 then
    print("及格")
else
    print("不及格")
end

循环结构

for 循环
lua 复制代码
-- 数值 for:起始值, 结束值, 步长(默认为 1)
for i = 1, 10 do
    print(i)
end

for i = 10, 1, -1 do
    print(i)
end

-- 注意:循环变量 i 在循环内部不可被修改
while 循环
lua 复制代码
local i = 1
while i <= 5 do
    print(i)
    i = i + 1   -- Lua 没有 i++ 或 i += 1 语法
end
repeat...until(类似 do-while)
lua 复制代码
local i = 1
repeat
    print(i)
    i = i + 1
until i > 5

六、全局表 _G

  • _G 是 Lua 的全局环境表,所有全局变量和函数都存储在其中
  • 可通过 _G["变量名"] 访问全局变量
  • 预定义函数(如 printtable.insert)也存放在 _G
lua 复制代码
a = 10
print(_G["a"])                     -- 10
print(_G["table"]["insert"])       -- function: 地址

七、字符串与字节操作

字符串与字节转换

lua 复制代码
local s = string.char(0x33, 0x34, 0x35)  -- 将 ASCII 码转为字符串 "345"
print(string.byte(s, 1))           -- 取第一个字符的 ASCII 码:51(0x33)
print(string.format("0x%02X", string.byte(s, 1)))  -- 格式化为十六进制:0x33

字符串长度

  • 使用 # 获取字符串字节数(对于 ASCII 字符串即字符数)
  • 对于多字节字符(如 UTF-8),需使用特定库获取正确字符数
lua 复制代码
print(#"hello")      -- 5
print(#"中文")       -- 6(UTF-8 下每个中文占 3 字节)

八、注意事项与小技巧

  1. 数组下标从 1 开始:这是 Lua 的传统,许多内置函数(如 table.insert)都基于此。
  2. 小心全局变量:尽量使用 local 避免污染全局空间。
  3. 类型自动转换:字符串与数字在算术运算时会尝试自动转换,但显式转换更安全。
  4. table 长度陷阱:#table 只对连续数字下标的数组部分有效,对字典部分无效。
  5. 多重赋值:可用于交换变量值,如 x, y = y, x
  6. 函数多返回值:若函数调用不在赋值语句最后,则只返回第一个值。

一个月前bellard大佬开源了用于嵌入式平台的MicroQuickJS引擎,本人完美错过,感兴趣的同学可以研究下,毕竟"所有能用JavaScript解决的问题,最后都会用JavaScript去解决"。

相关推荐
zhangrelay2 小时前
如何更环保(更省钱)的使用各类电子耗材/消耗品/易损件~电池为例
linux·笔记·学习
BlackWolfSky2 小时前
鸿蒙中级课程笔记2—状态管理V2—@Monitor装饰器:状态变量修改监听
笔记·华为·harmonyos
renhongxia12 小时前
TANDEM:多模态仇恨言论的时间感知神经检测
人工智能·深度学习·学习·语言模型·自然语言处理
●VON2 小时前
Flutter 与 OpenHarmony 技术选型分析:为何构建待办事项应用选择此组合?
学习·flutter·跨平台·von
QZ_orz_freedom2 小时前
后端学习笔记-HttpClient,微信登录
笔记·学习
修己xj2 小时前
Yank Note: 一款强大可扩展的本地 Markdown 笔记应用
笔记
pawpaw772 小时前
鑫通态HMI屏组态软件ApusIDE学习 - 显示GIF动画
学习·hmi·组态软件·鑫通态·apuside·组态屏
BlackWolfSky2 小时前
鸿蒙中级课程笔记2—状态管理V2—@Provider装饰器和@Consumer装饰器:跨组件层级双向同步
笔记·华为·harmonyos
胖少年2 小时前
Ubuntu 24.04 LTS apt autoremove 误删依赖致程序崩溃 解决与预防笔记
linux·笔记·ubuntu