学习一下Lua脚本x

数据类型#

据类型 描述
nil 无效值,比较时应该加上引号,同时会把nil看作false
boolean true - false
number 双精度浮点数
string 字符串,’hello’ | ‘hello’ ; 使用 [[ ]] 表示多行字符串
function 函数
userdata 自定义类型
thread 线程
table 关联数组,索引可以是数组或字符串,索引默认从1开始;可以表示数组、列表、字典、集合、哈希表; table 是可扩展的,可以随时添加或删除元素。

变量#

  1. 变量默认值为nil
  2. Lua 中的变量全是全局变量,哪怕是语句块或是函数里,除非用 local 显式声明为局部变量
  3. 赋值参考golang的赋值
  4. 连接字符串: a = "hello" .. "world"
  5. 没有赋到值的默认使用nil
  6. #len 表示数组,表的长度

循环#

  • while

    1
    2
    3
    4
    while(condition)
    do
    statements
    end
  • for

    这里默认就是起始值+最终值,然后每次加多少放第三个值

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    for i=1,f(x) do
    print(i)
    end

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

    -- 实例1 --
    function f(x)
    print("function")
    return x*2
    end
    for i=1,f(5) do print(i)
    end
    -- print: 1 2 3 4 5 7 8 9 10

    -- 实例2 --
    for i = 1, #myArray do
    print(myArray[i])
    end
  • repeat… until

  • break | goto

流程判断#

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
if(布尔表达式)
then
--[ 布尔表达式为 true 时执行该语句块 --]
else
--[ 布尔表达式为 false 时执行该语句块 --]
end

--[ 定义变量 --]
a = 10;

--[ 使用 if 语句 --]
if( a < 20 )
then
--[ if 条件为 true 时打印以下信息 --]
print("a 小于 20" );
end
print("a 的值为:", a);

函数#

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
-- 返回一个值 -- 
function max(num1, num2)

if (num1 > num2) then
result = num1;
else
result = num2;
end

return result;
end

-- 返回多个值 --
function maximum (a)
local mi = 1 -- 最大值索引
local m = a[mi] -- 最大值
for i,val in ipairs(a) do
if val > m then
mi = i
m = val
end
end
return m, mi
end

print(maximum({8,10,23,12,5}))

-- 可变参数 --
function average(...)
result = 0
local arg={...} --> arg 为一个表,局部变量
for i,v in ipairs(arg) do
result = result + v
end
print("总共传入 " .. #arg .. " 个数")
return result/#arg
end

print("平均值为",average(10,5,3,4,5,6))

迭代器#

pairs - ipairs

1
2
3
4
5
6
7
8
9
10
array = {"Google", "Runoob"}

for key,value in ipairs(array)
do
print(key, value)
end

-- print:
1 Google
2 Runoob

Table#

1
2
3
4
5
6
7
8
9
-- 初始化表
mytable = {}

-- 指定值
mytable[1]= "Lua"

-- 移除引用
mytable = nil
-- lua 垃圾回收会释放内存
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 数组
local t = {}
t[1] = "first"
t[2] = "second"

// map
local t = {}
t["key1"] = "value1"
t["key2"] = "value2"

// 嵌套
local t = {}
t.innerTable = {}
t.innerTable.value = 123

// 遍历 pairsipairs
for key, value in pairs(t) do
print(key, value)
end

内置函数#

自己查教程吧有 strings - table 的一些操作函数

Redis#

1
EVAL script numkeys key [key ...] arg [arg ...] 
  • script: 一段Lua脚本程序
  • numkeys: 用于指定键名参数的个数。
  • **key [key …]**: 从 EVAL 的第三个参数开始算起,表示在脚本中所用到的那些 Redis 键(key),这些键名参数可以在 Lua 中通过全局变量 KEYS 数组,用 1 为基址的形式访问( KEYS[1] , KEYS[2] ,以此类推)。
  • **arg [arg …]**: 附加参数,在 Lua 中通过全局变量 ARGV 数组访问,访问的形式和 KEYS 变量类似( ARGV[1] 、 ARGV[2] ,诸如此类)。

优点是可以保持redis执行多命令的原子性

在lua脚本中可以使用 redis.call() 来实现对redis的命令调用

实践#

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
supperQuestion = `
local kind = ARGV[1]
local userId = ARGV[2]
local qid = {}
local missing = {}
for i = 3, #ARGV do
local chapterId = ARGV[i]
local key = ""
if kind == "Chapter" then
key = "game:question:" .. chapterId
elseif kind == "Correct" then
key = "game:question:correct:" .. chapterId .. ":" .. userId
elseif kind == "Wrong" then
key = "game:question:wrong:" .. chapterId .. ":" .. userId
else
return redis.error_reply("kind error")
end
local res = redis.call("Smembers", key)
if #res > 0 then
for _, questionId in ipairs(res) do
table.insert(qid, questionId)
end
else
table.insert(missing, chapterId)
end
end
return {qid, missing} // 返回的是 []any
`

res, err := kernel.Kernel.MainCache.EvalCtx(ctx, supperQuestion, []string{}, args)

相信看了上面的内容这个东西就很好懂了,我也懒得分析了x