前言:最近在了解API网关apisix, 其中的配置都是用的lua, 于是开始了解lua。

语法

注释

  • 行注释 --
  • 块注释
1
2
3
--[[块
注释
--]]

变量

  • 布尔类型 nil, false 都认为false,其他包括数字0都是ture
  • double
  • 字符串
1
2
3
4
5
a = 'alo\n123"'
a = "alo\n123\""
a = '\97lo\10\04923"'
a = [[alo
123"]]
  • local声明变量为局部变量,否则默认为全部变量

控制语句

  • while循环
1
2
3
4
5
6
7
sum = 0
num = 1
while num <= 100 do
    sum = sum + num
    num = num + 1
end
print("sum =", sum)
  • if-else
1
2
3
4
5
6
7
8
9
a = 10 
b = 200
if a == 100 and b ~= 200 then
    print(1)
elseif a > 100 then
    print(2)
else
    print(3)
end
  • for
1
2
3
4
5
6
7
8
9
sum = 0 
for i = 1, 100 do 
    sum = sum + i
end
print(sum)
for i = 100, 1, -2 do
    sum = sum - i
end
print(sum)
  • until
1
2
3
4
5
sum = 2
repeat
    sum = sum ^ 2
    print(sum)
until sum > 1000

函数

  • 递归
1
2
3
4
5
function fib(n)
    if n < 2 then return 1 end
    return fib(n-2) + fib(n-1)
end
print(fib(10))
  • 闭包
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
function newCounter()
    local i = 0
    return function()  -- anonymous function
        i = i + 1
        return i
    end
end

c = newCounter()
print(c()) -- 1
print(c()) -- 2
  • 返回值:杜宇的被丢弃,少了的变量为nil
1
2
3
4
5
6
7
function getUserInfo(id)
    print(id)
    return "hello", 123
end
a, b, c = getUserInfo()
print(a, b, c)
-- id 和 c 均为nil

table

table可以用nil以外的对象做key和value, 可以用来描述原始的数组、字典等 - 字典

1
2
3
4
5
6
7
a = {name="foo", age=20}
a.sex = 'm'

-- 遍历
for k, v in pairs(a) do
    print(k, v)
end

注:全局变量存在_G的table

  • 数组
    • 下标从1开始
    • 可以混合类型
    • 数组长度使用#arr获取
1
2
3
4
5
arr = {10, 20, 30}
arr = {[1]=10, [2]=20, 3=[30]}

-- 获取长度
print(#a)

MetaTable 和 MetaMethod

  • 内建MetaMethod方法
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
__add(a, b)                     对应表达式 a + b
__sub(a, b)                     对应表达式 a - b
__mul(a, b)                     对应表达式 a * b
__div(a, b)                     对应表达式 a / b
__mod(a, b)                     对应表达式 a % b
__pow(a, b)                     对应表达式 a ^ b
__unm(a)                        对应表达式 -a
__concat(a, b)                  对应表达式 a .. b
__len(a)                        对应表达式 #a
__eq(a, b)                      对应表达式 a == b
__lt(a, b)                      对应表达式 a < b
__le(a, b)                      对应表达式 a <= b
__index(a, b)                   对应表达式 a.b
__newindex(a, b, c)             对应表达式 a.b = c
__call(a, ...)                  对应表达式 a(...)
  • setmetatable: 实现重载操作符等功能
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
-- 重载__add 实现分数加法
fraction_a = {numerator=2, denominator=3}

fraction_b = {numerator=4, denominator=4}

fraction_op = {}

function fraction_op.__add(f1, f2)
    ret = {}
    ret.numerator = f1.numerator * f2.denominator + f2.numerator * f1.denominator
    ret.denominator = f1.denominator * f2.denominator
    return ret
end

setmetatable(fraction_a, fraction_op)
setmetatable(fraction_b, fraction_op)


fraction_s = fraction_a + fraction_b
-- fraction_s = fraction_op.__add(fraction_a, fraction_b)
for k ,v in pairs(fraction_s) do
    print(k, v)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
-- 重载__index,当调用table[key]在本身找不到是回去__index指向的对象中查找
window_prototype = {x=0, y=0, width=100, height=100}

myWin = {title="Hello"}

setmetatable(myWin, {__index = window_prototype})

for k, v in pairs(myWin) do
    print(k, v)
end
print(myWin.x)

“面向对象”

 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
Person={}
function Person:new(p)
    local obj = p
    if (obj == nil) then
        obj = {name="Unknown", age=0, handsome=false}
    end
    self.__index = self
    return setmetatable(obj, self)
end
function Person:toString()
    return self.name .. " : " .. self.age .. " : " .. (self.handsome and "handsome" or "ugly")
end

no_one = Person:new()
print(no_one:toString())
data = {name="PPD", age=28, handsome=true}
me = Person:new(data)
print(me:toString())

-- 继承
Student = Person:new()
function Student:new()
    newObj = {year = 2013}
    self.__index = self
    return setmetatable(newObj, self)
end
function Student:toString()
    return "Student : ".. self.year.." : " .. self.name
end

模块

  • 单次载入
1
require("model_name")
  • 多次载入
1
dofile("model_name")
  • 惰性载入
1
2
local hello = loadfile("model_name")
hello()

参考