Redis基础知识(学习笔记21--Lua 脚本语言)
1 Lua 简介
Lua 是一个由标准C语言开发的、开源的、可扩展的、轻量级的、弱类型的、解释型脚本语言,是于1993年由巴西里约热内卢天主教大学(Pontifical Catholic University of Rio de Janeiro)的三人研究小组使用标准C语言开发。
2 安装
注意 源码安装时,需要先安装gcc-c++
yum - y install gcc-c++
安装过程不在赘述
安装后,可以通过以下命令查询程序路径
whereis lua
3 语法基础
3.1 注释
Lua的行注释为两个连续的减号,段注释以--[[ 开头,以--]] 结束。
3.2 数据类型
Lua 中有8种类型,分布为:nil、boolean、number、string、userdata、function、thread 和 table。通过type()函数可以查看一个数据的类型。
数据类型 | 描述 |
nil | 只有值nil属于该类,表示一个无效值,与Java中的null类似。但在条件表达式中相当于false。 |
boolean | 包含两个值:false和true。 |
number | 表示双精度类型的实浮点数。 |
string | 字符串,由一对双引号或单引号括起来。当一个字符串包含多行时,可以在第一行中以 [[ 开头,在最后一行中以 ]] 结尾,那么在 [[ 与 ]] 括起来的这多行内容就是一个字符串。换行符为字符串“\n”。 |
table | 类似于Java中的数组,但比数组的功能更强大,更灵活。 |
function | 由 C 或 Lua 编写的函数 |
thread | 协同线程,是协同函数的执行体,即正在执行的协同函数。 |
userdata | 一种用户自定义函数,用于表示一种由应用函数或C/C++语言库所创建的类型,可以将任意C/C++的任意数据类型的数据存储到Lua变量中调用。 |
3.3 标识符
标识符主要包含保留字、变量、常量、方法名、函数名、类名等。Lua的标识符由字母、数字与下划线组成,但不能以数字开头。Lua是大小写敏感的。
(1)保留字
Lua常见的保留字共有22个。不过,除了这22个外,Lua中还定义了很多的内置全局变量,这些内置全局变量的一个共同特征是,以下划线开头后跟全是大写字母。所以,我们在定义自己的标识符时不能与这些保留字、内置全局变量重复。
and | break | do | else |
elseif | end | false | for |
function | if | in | local |
nil | not | or | repeat |
return | then | true | until |
while | goto |
(2)变量
Lua是弱类型语言,变量不需类型声明即可直接使用。变量分为全局变量和局部变量。Lua中的变量默认都是全局变量,即使声明在语句块或函数里。全局变量一旦声明,在当前文件中的任何地方都可以访问。局部变量local相当于Java中的private变量,只能在声明的语句块中使用。
(3)动态类型
Lua是动态类型语言,变量的类型可以随时改变,无需声明。
3.4 运算符
运算符是一种特殊的符号,用于告诉解释器执行特定的数学或者逻辑运算。Lua提供了以下几种运算符类型。
(1)算数运算符
设定A的值为10,B的值为20.
操作符 | 描述 | 实例 |
+ | 加法 | A+B 输出结果 30 |
- | 减法 | A-B 输出结果 -10 |
* | 乘法 | A*B 输出结果 200 |
/ | 除法 | 5/2 输出结果 2.5 |
% | 取余 | B%A 输出结果 0 |
^ | 乘幂 | A^2 输出结果 100 |
- | 负号 | -A 输出结果是 -10 |
// | 整除运算符(>=lua 5.3) | 5//2 输出结果 2 |
注意:
在 整除运算符 时,例如 5//2,可能会报错:
lua: a.lua: XXX : unexpected symbol near '/' ---XXX 代表行号
报错原因时版本的问题。需要 >=lua 5.3。
(2)关系运算符
设定A的值为10,B的值为20.
操作符 | 描述 | 示例 |
== | 等于 | (A==B)为false |
~= | 不等于 | (A~=B) 为true |
> | 大于 | (A>B)为false |
< | 小于 | (A<B)为true |
>= | 大于等于 | (A>=B)为false |
<= | 小于等于 | (A<=B)为true |
(3)逻辑运算符
注意:Lua系统将false 与 nil 作为假,将true 与非nul作为真,即使是0也为真。
设定A的值为true,B的值为false。
操作符 | 描述 | 示例 |
and | 逻辑与 | (A and B) 为false |
or | 逻辑或 | (A or B) 为true |
not | 逻辑非 | not (A and B) 为true |
(4)其它运算符
操作符 | 描述 | 示例 |
.. (两个点) | 字符串连接符 | a..b,其中a为“Hello”,b为“ World”, 输出结果为“Hello World”。 |
# | 返回字符串或表的长度 | #Hello,输出结果为5。 |
3.5 函数
Lua中函数的定义是以function开头,后跟函数名与参数列表,以end结尾。其可以没有返回值,也可以一次返回多个值。
(1)固定函数
Lua中的函数在调用时与Java语言中方法的调用是不同的,其不要求实参的个数必须与函数中形参的个数相同。如果实参个数少于形参个数,则系统自动使用nil填充;如果实参个数多于形参个数,多出的将被系统自动忽略。
(2)可变参函数
在函数定义时不给出具体形参的个数,而是使用三个连续的点号。在函数调用时就可以向该函数传递任意个数的参数,函数可以全部接收。
(3)可返回多个值
Lua 中的函数一次可以返回多个值,但需要有多个变量来同时接收。
(4)函数作为参数
Lua的函数中,允许函数作为参数。而作为参数的函数,可以是已经定义好的普通函数,也可以是匿名函数。
3.6 流程控制语句
Lua提供了if作为流程控制语句
(1)if 语句
Lua 提供了if ... then 用于表示条件判断,其中if的判断条件可以是任意表达式。 Lua系统将false 与 nil 作为假,将true 与 非 nil 作为真,即使是0也是真。
需要注意,Lua中的if语句的判断条件可以使用小括号括起来,也可以不使用。
(2)if 嵌套语句
Lua中提供了专门的关键字elseif来做if嵌套语句。
注意,不能使用else 与 if 两个关键字的联用形式,即不能使用else if 来嵌套if语句。
3.7 循环控制语句
(1)While ... do
只要while 中的条件成立就一直循环。
(2)repeat ... until
until 中的条件成立了,循环就要停止了。
(3)数值for
这种for循环只,用于循环变量为数值型的情况。其语法格式为:
for var=exp1,exp2,exp3 do
exp2,为条件(exp2>=exp1);
exp3 ,为步长,省略不写时,默认为1。
(4)泛型for
泛型for用于遍历table中的所有值,其需要与Lua的迭代器联合使用。
(5)break
break语句可以提前终止循环。其只能用于循环之中。
(6)goto
goto语句可以将执行流程无条件地跳转到指定的标记语句处开始执行,注意,是开始执行,并非仅执行这一句,而是从这句开始后面的语句都会重新执行。当然,该标识语句在第一次经过时也会执行的,并非是必须由goto跳转时才执行。
语句标识使用一对双冒号括起来,置于语句前面。goto语句可以在循环之外。
注意,Lua5.1 中不支持双冒号的语句标记。
4 语法进阶
4.1 table
(1)数组
使用table 可以定义一维、二维、多维数组。不过,需要注意,Lua中的数组索引是从1开始的,且不需声明数组长度,可以随时增加元素。当然。同一数组中的元素可以是任意类型。
(2)map
使用map也可以定义出类似map的key-value数据结构。其可以定义table时直接指定key-value,也可单独指定key-value。而访问时,一般都是通过table的key直接访问,也可以数组索引方式来访问,此时的key即为索引。
(3)混合结构
Lua允许将数组与key-value混合在同一个table中进行定义。key-value不会占用数组的数字索引值。
(4)table 操作函数
Lua 中提供了对table进行操作的函数。
table.concat ()
【函数】table.concat (list [, sep [, start [, end]]])
【解析】该函数用于将指定的table数组进行字符串连接。连接从start索引位置到end索引位置的所有数组元素,元素间使用指定的分隔符sep隔开。如果table是一个混合结构,那么这个连接与key-value无关,仅是连接数组元素。
table.pack()
【函数】table.pack (···)
【解析】打包。该函数的参数是一个可变参,其可将指定的参数打包为一个table返回。这个返回的table中具有一个属性n,用于表示该table包含的元素个数。Lua5.1 不支持该函数。
table.unpack()
【函数】table.unpack (list [, i [, j]])
【解析】拆包。该函数返回指定table的数组中的从第 i 个元素到第 j 个元素值。 i 与 j是可选的,默认i为1,j为数组的最后一个元素。Lua5.1 不支持该函数。
table.maxn()
【函数】table.maxn(table)
【解析】该函数返回指定table的数组中的最大索引值,即数组包含元素的个数。
table.insert()
【函数】table.insert (list, [pos,] value)
【解析】该函数用于在指定table的数组部分指定位置pos插入值为value的一个元素。其后的元素会被后移。pos参数可选,默认为数组部分末尾。
table.remove()
【函数】table.remove (list [, pos])
【解析】该函数用于删除并返回指定table中数组部分位于pos位置的元素。其后的元素会被迁移。pos参数可选,默认删除数组中的最后一个元素。
table.sort()
【函数】table.sort (table [, fun(a,b)])
【解析】该函数用于对指定table的数组进行升序排序,也可以按照指定函数fun(a,b)中指定的规则进行排序。fun(a,b)是一个用于比较a与b的函数,a与b分别代表数组中的两个相邻元素。
注意;
- 如果arr中的元素既有字符串又有数值型,那么对其进行排序会报错。
- 如果数组中多个元素相同,则其相同的多个元素的排序结果不确定,即这些元素的索引谁排前排后,不确定。
- 如果数组元素中包含nil,则排序会报错。
学习笔记--参阅特别声明
1.【Redis视频从入门到高级】
【https://www.bilibili.com/video/BV1U24y1y7jF?p=11&vd_source=0e347fbc6c2b049143afaa5a15abfc1c】