非常小巧的语言,在单片机、go相关库、游戏脚本等都遇到过。快速学习一下。
最新版本5.4,源代码相当小
在ubuntu下编译: make linux test 然后安装 make install
直接运行lua则在窗口中即时运行,也可以lua xx.lua运行代码。
它是一个区分大小写的语言
注释
– 单行注释
–[[ 多行注释 ]]–
变量
默认情况下,变量总是全局的。
没有初始化的变量值为nil
删除变量,则是赋值为nil
变量类型
nil
boolean
number 双精浮点
string 字串,双引号或单引号
function 函数
userdata
thread 独立线程
table 表
通过type可以给出变量类型 print(type(10.4))
nil作比较时应该加上双引号 type(x)==“nil”
flase和nil为false,其它均为true,数字0也是true
对数字字符串进行算术操作时,会尝试转换为数字进行运算
print("2"+6) 返回8.0
print("2+5") 返回2+5
print("2"+"6") 返回8.0
字符串连接使用..
print("a".."b")
print(1223..456)
#计算字符串长度 print(#len)
local tab1 = {} --创建一个空表(局部变量)
local tab2 = {"apple", "pear"}
a = {}
a["key"] = "value"
key = 10
a[key] = 22
a[key] = a[key] + 11
for k, v in pairs(a) do
print(k .. " : " .. v)
end
运行结果:
10 : 33
key : value
默认初始索引一般以 1 开始
local tbl = {"apple", "pear", "orange", "grape"}
for key, val in pairs(tbl) do
print("Key", key)
end
table 不会固定长度大小,有新数据添加时 table 长度会自动增长,没初始的 table 都是 nil。
函数可以存在变量里
可以以匿名函数的方式通过参数传递
Lua变量有三种:全局、局部、表中的域
赋值
a,b = 10, 2*x 对多个变量同时赋值
x, y = y, x 交换xy
控制
while(true)
do
end
if(0) --0为true
then
end
函数
可以将函数作为参数传递给函数
function add(…) –可变参数
function add(...)
local s = 0
for i,v in ipairs{...} do
s = s + v
end
return s
end
do
function foo(...)
for i = i, select('#', ...) do --获取参数总数
local arg = select(i, ...); --读取参数
print("arg", arg);
end
end
end
Lua运算
% 取余
~= 不等于
and or not
.. 连接字符串
# 字符串或表的长度
Lua字符
单引号、双引号、[[]]号
\r \n \0
string.upper 转大写
string.lower 转小写
string.gsub(mainString,findString,replaceString,num) 替换
string.find(str,substr,[init,[end]]) 搜索
string.reverse(arg) 字符反转
string.format() 格式化字符串
string.char(arg) 整数转字符
string.byte(arg[,int]) 转字符为整数
string.len(arg) 长度
string.rep(string,n) 拷贝n次字符串
string.gmatch(str,pattern) 迭代器函数
string.match(str,pattern,init) 寻找匹配
string.sub(s, i [,j]) 字符串截取
数组
array = {"a","b"}
for i = 0, 2 do
print(array[i])
end
输出nil a b
迭代器
迭代函数ipairs,用于遍历数组的每一个元素
table
用来帮助我们创建不同的数据类型,如数组、字典等
mytable = {} 初始化表
mytable[1] = "Lua" 指定值
mytable = nil 移除引用,lua会释放内存
table.concat(table[,sep[,start[,end]]]) 连接
table.insert(table,[pos,]value ) 插入元素
table.remove(table[,pos]) 移除元素
table.sort() 排序
模块与包
模块类似于封装库
Lua的模块是由变量、函数等已知元素组成的table。
-- module.lua
-- 定义一个名为module的模块
module = {}
--定义一个常量
module.constant = "这是一个常量"
--定义一个函数
function module.func1()
io.write("这是一个公有函数!\n")
end
local function func2()
print("这是一个私有函数!")
end
require("<模块名>") 加载模块
requeire “<模块名>”
执行require后会返回一个由模块常量或函数组成的table
require("module")
print(module.constant)
module.func3()
local m = require("module") --别名变量
print(m.constant)
m.func3()
加载机制
加载模块的路径存放在全局变量package.path中。当lua启动后,会以环境变量LUA_PATH的值来初始化这个变量。
C包
与Lua中写包不同,C包在使用前必须首先加载并连接
Lua在一个叫loadlib的函数内提供了所有的动态连接的功能。
local path = "/usr/local/libluasocket.so"
local f = loadlib(path, "luaopen_socket")
f() --真正打开库
协同程序 coroutine
线程和协同程序的区别:线程各自独立,协程需要彼此协作运行。与其它协程共享全局变量和其它大部分东西。
coroutine.create() 创建
coroutine.resume() 重启
coroutine.yield() 挂起
coroutine.status() 查看状态
coroutine.wrap() 创建,同create
coroutine.running() 返回正在运行的协程
co = coroutine.create(
function(i)
print(i);
end
)
coroutine.resume(co, 10) -- 10 启用协程
print(coroutine.status(co)) -- dead
print("----------")
co = coroutine.wrap(
function(i)
print(i);
end
)
co(1) --运行协程,输出1
print("----------")
co2 = coroutine.create(
function()
for i=1,10 do
print(i)
if i == 3 then
print(coroutine.status(co2)) --running
print(coroutine.running()) --thread:XXXXXX
end
coroutine.yield() --挂起,后续暂不执行
end
end
)
coroutine.resume(co2) --1 恢复
coroutine.resume(co2) --2
coroutine.resume(co2) --3
print(coroutine.status(co2)) -- suspended
print(coroutine.running())
print("----------")
IO
file = io.open(filename [, mode])
r 只读 w 只写 a 添加 r+ 打开可读写 w+ 清除可读写 a+ 添加可读写 b 二进制
简单模式
file = io.open("test.lua","r")
io.input(file) --设置默认输入文件为test.lua
print(io.read()) --输出文件第一行
io.close(file)
io.tmpfile() 返回一个临时文件句柄
io.type(file) 检测对象是否为可用的句柄
io.flush() 向文件写入缓冲中的数据
io.lines() 返回一个迭代函数,每次调用将获得文件中的一行内容
完全模式
同一时间处理多个文件
错误处理
assert 和 error
local function add(a,b)
assert(type(a)=="number","a不是一个数字")
assert(type(b)=="number","b不是一个数字")
return a+b
end
add(10)
error(message [, level]) 终止正执行的函数,返回message作为错误信息
pcall xpcall debug
pcall 接收函数和参数,并执行,返回结果:有错误、无错误
(似乎是用于函数的测试)
xpcall 可以指向一个错误处理函数
if pcall(function_name, ...) then
--没错
else
--有错
end
https://www.runoob.com/lua/lua-object-oriented.html
树莓派上使用lua
https://www.mobibrw.com/2018/14357
https://github.com/vsergeev/lua-periphery Linux Peripheral I/O (GPIO, LED, PWM, SPI, I2C, MMIO, Serial) with Lua
在网上下载了一个Lua5.4中文版,它支持中文关键词
它修改的关键词不太符合我的语法,做了一些修改:
llex.c 常见关键字
其它的关键字,可以搜索源代码中的 static const luaL_Reg