Lua是一种开源、简单易学、轻量小巧的脚本语言,用标准C语言编写。
其设计的目的就是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。
Redis从2.6版本开始支持Lua脚本,Redis使用Lua可以:
Linux安装Lua :
curl -R -O http://www.lua.org/ftp/lua-5.3.0.tar.gz
tar zxf lua-5.3.0.tar.gz
cd lua-5.3.0
make linux test
make install
编写Hello.lua
文件:
print('hello world')
执行命令:
lua Hello.lua
Lua
提供交互式编程,可以在命令行中输入命令并立即查看结果。
Lua
脚本也可以保存在一个以lua
为结尾的文件,并执行。
Lua
注释的符号是两个减号 :
-- 这是一行注释
--[[
这是多行注释
--]]
print('这是一行代码')
Lua
的关键字 :
and | break | do | else |
elseif | end | false | for |
function | if | in | local |
nil | not | or | repeat |
return | then | true | until |
while | goto |
Lua
中的变量总是全局的。
Lua
有八个基本类型:
数据类型 | 描述 |
---|---|
nil | 这个最简单,只有值nil属于该类,表示一个无效值(在条件表达式中相当于false)。 |
boolean | 包含两个值:false和true。 |
number | 表示双精度类型的实浮点数 |
string | 字符串由一对双引号或单引号来表示 |
function | 由 C 或 Lua 编写的函数 |
userdata | 表示任意存储在变量中的C数据结构 |
thread | 表示执行的独立线路,用于执行协同程序 |
table | Lua 中的表(table)其实是一个"关联数组"(associative arrays),数组的索引可以是数字、字符串或表类型。在 Lua 里,table 的创建是通过"构造表达式"来完成,最简单构造表达式是{},用来创建一个空表。 |
nil
print(a)
a
是未初始化的,打印a
就会输入nil值。
boolean
boolean
类型有两个值:true
和 false
。Lua
也会把nil
当成false
值,但false
不等于nil
。与C语言不一样,0
在Lua
中是true
print(a == nil) -- true
print(false == nil) -- false
if(a) then
print(1)
else
print(0) -- print 0
end
number
number
默认只有一种类型:double
。
string
string
可以用双引号、单引号来表示,也可以用[[]]
来表示一块字符串。
str = [[
中括号中的字符串会报保
留tab和换行
]]
print(str)
string
在与number
进行算数运算,会尝试将字符转化为数字
numStr = '1'
num = 3
print(numStr + num) -- print 4
使用#
计算字符串的长度:
print(#'这是一行字符串')
table
-- 创建一个空的 table
local tbl1 = {}
-- 直接初始表
local tbl2 = {"apple", "pear", "orange", "grape"}
Lua
的数组从1
开始。
function
thread
userdata
Lua
的变量默认为全局变量,声明局部变量使用local
关键字。
Lua
中的循环有 :while
、for
、repeat
:
while循环 :
a=10
while( a < 20 )
do
print("a 的值为:", a)
a = a+1
end
For循环:
for i=1,f(x) do
print(i)
end
for i=10,1,-1 do
print(i)
end
Repeat循环 :
--[ 变量定义 --]
a = 10
--[ 执行循环 --]
repeat
print("a的值为:", a)
a = a + 1
until( a > 15 )
使用break
和goto
可以跳出循环。
操作符 | 描述 | 实例 |
---|---|---|
== | 等于,检测两个值是否相等,相等返回 true,否则返回 false | (A == B) 为 false。 |
~= | 不等于,检测两个值是否相等,相等返回 false,否则返回 true | (A ~= B) 为 true。 |
> | 大于,如果左边的值大于右边的值,返回 true,否则返回 false | (A > B) 为 false。 |
< | 小于,如果左边的值大于右边的值,返回 false,否则返回 true | (A < B) 为 true。 |
>= | 大于等于,如果左边的值大于等于右边的值,返回 true,否则返回 false | (A >= B) 返回 false。 |
<= | 小于等于, 如果左边的值小于等于右边的值,返回 true,否则返回 false | (A <= B) 返回 true。 |
操作符 | 描述 | 实例 |
---|---|---|
and | 逻辑与操作符。 若 A 为 false,则返回 A,否则返回 B。 | (A and B) 为 false。 |
or | 逻辑或操作符。 若 A 为 true,则返回 A,否则返回 B。 | (A or B) 为 true。 |
not | 逻辑非操作符。与逻辑运算结果相反,如果条件为 true,逻辑非为 false。 | not(A and B) 为 true。 |
操作符 | 描述 | 实例 |
---|---|---|
.. | 连接两个字符串 | a..b ,其中 a 为 "Hello " , b 为 "World", 输出结果为 "Hello World"。 |
# | 一元运算符,返回字符串或表的长度。 | #"Hello" 返回 5 |
Redis
使用Lua
脚本主要用三个命令 :
示例:
eval "redis.call('set',KEYS[1],ARGV[1])" 1 K1 'V1'
eval "return redis.call('get',KEYS[1])" 1 K1
EVAL script numkeys key [key ...] arg [arg ...]
-- numberkeys是key的个数
DefaultRedisScript<Boolean> redisScript = new DefaultRedisScript<>();
redisScript.setScriptSource(new ResourceScriptSource(new ClassPathResource("lua/BATCH_UPDATE.lua")));
redisScript.setResultType(Boolean.class);
redisTemplate.execute(redisScript, Collections.singletonList(key), Collection.singletonList(fakeDataList));
local dataStr = KEYS[1]
local dataList = loadstring("return"..dataStr)
for index,data in dataList do
redis.call('SET',data[name],'EX',data[timeInterval])
end
return true
redisson.getBucket("foo").set("bar");
String r = redisson.getScript().eval(Mode.READ_ONLY,
"return redis.call('get', 'foo')", RScript.ReturnType.VALUE);
// 通过预存的脚本进行同样的操作
RScript s = redisson.getScript();
// 首先将脚本保存到所有的Redis主节点
String res = s.scriptLoad("return redis.call('get', 'foo')");
// 返回值 res == 282297a0228f48cd3fc6a55de6316f31422f5d17
// 再通过SHA值调用脚本
Future<Object> r1 = redisson.getScript().evalShaAsync(Mode.READ_ONLY,
"282297a0228f48cd3fc6a55de6316f31422f5d17",
RScript.ReturnType.VALUE, Collections.emptyList());
当 Redis 的 持久化策略为 RDB 情况下,不会对脚本进行持久化!!!
当 Redis 的 持久化策略为 RDB 情况下,不会对脚本进行持久化!!!
当 Redis 的 持久化策略为 RDB 情况下,不会对脚本进行持久化!!!