前言
最近实在太摸辣! 前景提要:收了个 小米AC2100 刷了 OpenWrt 系统,那个固件带了一个微信推送,但是我觉得不是特别好用,准备自己弄一个 基于
linux netlink、ASP.NET Core做后端,使用MQTT或者Google FCMMi Push做推送。Luci用lua脚本编写插件,反正也没什么事就来看看lua吧!为什么叫lua不叫rua
关于 lua
Lua 是一种轻量小巧的脚本语言,用标准C语言编写并以源代码形式开放, 其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。
lua 很轻量、与 C/C++ 交互方便、支持 面向过程 or 函数式 编程。
环境安装
直接摁包管理器!
Scoop: scoop install lua
如果包管理器没有就解压扔环境变量呗
运行方式
脚本运行
lua 脚本是文本文件
script:
| |
script.lua:
| |
还可以在命令行中输入 lua -i 来使用 lua REPL
数据类型
lua 语言有如下几种数据类型
- nil: null,未定义的变量为
nil,同样,可以给变量赋值nil来“销毁” 它 - boolean: true / false,条件表达式中只有
nil和false为否,其余(包括数字0皆为是 - number: 数字类型,双精度浮点实数,所有的数字都是
number类型 - string: 字符串,使用
"或'包裹,..连接。多行字符串可以使用[[和]]包裹 - function: C 或 lua 函数(可以类似于委托来使用)
- userdata: 用户类型
- thread: 用于协程
- table: 表,类似于 PHP 中的 “数组”,可以存储数组或键值对之类的
获取类型
在 lua 中,可以使用 type() 函数来获取类型,比如
| |
在上述案例中,unknow 未定义,所以输出为 nil
注意,判断 nil 时候应该加上引号,因为 typeof 的结果是字符串类型:
| |
string 类型
string 就是字符串,很正常的一个字符串。转义字符也都一样。
string 初始化
前面说过了,可以用双引号也可以用单引号:
| |
当然,用 [[ 和 ]] 包裹显示 “多行字符串” 或者 “原字符串”,类似于 C# 中的 @"" 或者 python 中的 r""。
string 相关函数使用
- 字符串连接:
..; - 大小写转换:
string.upper(str)和string.lower(arg); - 替换:
string.gsub(str, search, replace, [times]),次数省略为不限次数; - 查找:
string.find(str, search, [init, [regxp]]),返回两个值:起始位置和结束位置; - 反转:
string.reverse(str); - 格式化:
string.format(...),格式化规则类似于printf; - 字符与 ASCII 代转换:
string.char(nums)字符串中的字符转 ASCII 码返回,string.byte(str, [index]); - 计算长度:
string.len(str)或#,例如#str; - 重复字符串:
string.rep(str, times),重复times次字符串str; - 正则字符串:
string.match(str, pregxp, init)只寻找源字串str中的第一个配对并返回结果,找不到时返回nil;
你说 number 转 string? 使用数字运算符的时候会自动尝试将 string 转为 number,所以可以写类似于
| |
当然,单纯需要转换的话可以使用 tostring() 和 tonumber() 函数。
更多字符串操作参考 Lua 5.4 官方文档
table 类型
这个 table 很神奇,反正类比一下 PHP 的 “数组”,这玩意也是一个 “什么都能塞” 的角
table 的初始化
table 使用初始化器 {} 来初始化,如下代码初始化了一个 table:
| |
在初始化时候,如果需要指定索引的键,则可以使用 [] 索引器,说起来有点抽象,看看代码:
| |
没错,[]不仅在索引时候用,在创建的时候还可以用来表示键,虽然我不知道这时候他叫什么。不过,为了方便起见,索引 key 为字符串的时候,可以省略掉 [] 而使用 .,比如
| |
创建的时候也可以省略 [],比如
| |
哦对了,还有一个很生草的事情,在 lua 中,索引是从 1 开始的,这一点也不反人类但是反程序员。
其他类型不再赘述
table 相关函数使用
- 连接各元素:
table.concat(table, [sep , [start ,[end]]]),实际上有些像string.Join的功能,将各元素连接起来; - 插入元素:
table.insert(table, [pos] ,value),在pos位置插入value,省略默认为尾部插入; - 删除元素:
table.remove (table, [pos])删除pos位置的值,并返回,省略默认为尾部删除; - 排序:
table.sort (table, [comp])默认为升序排序;
或许大概没准是由于 table 存的东西奇奇怪怪,Lua 并没有提供计算长度的函数,用
#运算符也会有问题,那就手搓遍历罢(悲
function 类型
函数作为一个基础类型出现在这里,可以类比委托或者类似于 js 的 function 那样,既可以调用也可以作为一个变量/参数传递。
首先是函数定义:
| |
需要局部函数可以在 function 前面加修饰符 local,返回值可以有多个。
可变参数 function:
| |
将函数赋值给变量:
| |
基础用法大概差不多这样,其它类型留到以后再说或者不再赘述。
运算符
算术运算符
除了常规的 + - * / % 之外,还有 ^(幂)和 //(整除)
关系运算符
常规的 == <= >= < > 之外,不等于用 ~=
逻辑运算符
不是 || 这些符号,而是类似于 python,用 and or not
其他运算符
一个是计算长度用的 #,一个是连接字符串的 ..(其实这大概也算是算术运算符?)
流程控制
流程控制嘛其实说白了就是 if-else,具体使用代码如下所示:
| |
有些类似于 SQL 中的判断嘛
Lua 的 if-else 可以嵌套使用 废话
循环
while 循环
如下所示
| |
for 循环
| |
说说这个 for 吧,for 后面是 var=exp1,exp2,exp3 其中表达式1是初始值,表达式2是终止值,表达式3为步长,比如我要输出 100 以内 可以被 3 整除的数,可以这么写:
| |
另外很重要一个用途就是遍历 table 之类的,这玩意叫“泛型 for 循环”,实际上很类似于 foreach:
| |
至于这个 ipairs() 函数,是 Lua 的一个迭代器,后续细说怎么个回事。
repeat…until(类似 do-while 循环)
| |
很类似 do-while 的一个玩意
果然各种语言里面最花的都是
for嘛 pythone: 喵喵喵??
变量
标识符的规则和关键字不再赘述了,各家都大同小异的
另外就是 Lua 有全局变量和局部变量,默认的变量是全局变量,用 local 关键字修饰后才是局部变量,比如:
| |
写的有点乱反正就是这么回事(摆烂