Lua语言学习

4.8k 词

Lua

网上教程

Lua简明教程

极客学院Openresty教程

Windows安装

使用 tasklist /fi "imagename eq nginx.exe" 命令查看 nginx 进程,其中一个是 master 进程,另一个是 worker 进程

cmd进入nginx的安装目录,输入start nginx.exe来启动nginx

cmd进入nginx的安装目录,输入nginx -s reload来重启nginx

LuaJIT部分语法

环境搭建

1
2
3
4
5
6
7
wget http://luajit.org/download/LuaJIT-2.1.0-beta1.tar.gz
tar -xvf LuaJIT-2.1.0-beta1.tar.gz
cd LuaJIT-2.1.0-beta1
make
sudo make install

luajit -v

基础数据类型

nil

无效值

boolean

falsenil为假,其余包括0全部为真。

number

实数类型,可以用math.floor向下取整和math.cell向上取整。

string

'abc'"abc"[=[abcn]=](不转义)

字符串不可改变,只能新建,相同字符串在内存中只有一个副本

table

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
local corp = {
web = "www.google.com",
-- value = "www.google.com"
telephone = "12345678", --索引为字符串
staff = {"Jack", "Scott", "Gary"}, --索引为字符串,值也是一个表
100876, --相当于 [1] = 100876,此时索引为数字
-- key = 1, value = 100876
100191, --相当于 [2] = 100191,此时索引为数字
[10] = 360, --直接把数字索引给出
["city"] = "Beijing" --索引为字符串
}

print(corp.web) -->output:www.google.com
print(corp["telephone"]) -->output:12345678
print(corp[2]) -->output:100191
print(corp["city"]) -->output:"Beijing"
print(corp.staff[1]) -->output:Jack
print(corp[10]) -->output:360

function

1
2
3
4
5
function ()
end

foo = function ()
end

表达式

a and b 如果a为nil,则返回a,否则返回b
a or b 如果a为nil,则返回b,否则返回a
not a 返回true or false

字符串拼接

1
2
3
4
5
6
7
8
print("Hello " .. "World")    -->打印 Hello World
print(0 .. 1) -->打印 01 自动将数字转化为string

str1 = string.format("%s-%s","hello","world")
print(str1) -->打印 hello-world

str2 = string.format("%d-%s-%.2f",123,"world",1.21)
print(str2) -->打印 123-world-1.21

字符串拼接会不断的创建新字符串,若在循环中进行拼接,则对性能有较大影响,推荐使用table.concat()

1
2
3
4
5
local pieces = {}
for i, elem in ipairs(my_list) do
pieces[i] = my_process(elem)
end
local res = table.concat(pieces)

控制语句

if

1
2
3
4
x = 10
if x > 0 then
print("x is a positive number")
end

if-else

1
2
3
4
5
6
x = 10
if x > 0 then
print("x is a positive number")
else
print("x is a non-positive number")
end

if-elseif-else

1
2
3
4
5
6
7
8
9
score = 90
if score == 100 then
print("Very good!Your score is 100")
elseif score >= 60 then
print("Congratulations, you have passed it,your score greater or equal to 60")
--此处可以添加多个elseif
else
print("Sorry, you do not pass the exam! ")
end

嵌套if

1
2
3
4
5
6
7
8
9
10
11
12
score = 0
if score == 100 then
print("Very good!Your score is 100")
elseif score >= 60 then
print("Congratulations, you have passed it,your score greater or equal to 60")
else
if score > 0 then
print("Your score is better than 0")
else
print("My God, your score turned out to be 0")
end --与上一示例代码不同的是,此处要添加一个end
end

while

break,无continue

1
2
3
while 表达式 do
--body
end

repeat

一直执行,直到条件为真

1
2
3
repeat
body
until 条件

for

数字 for(numeric for)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
for var = begin, finish, step do
--body
end

for i = 1, 5 do
print(i)
end

-- output:
1
2
3
4
5
  1. var从begin取到finish,左右都为闭区间
  2. begin、finish、step 三个表达式只会在循环开始时执行一次
  3. 第三个表达式 step 是可选的,默认为 1
  4. 控制变量 var 的作用域仅在 for 循环内,需要在外面控制,则需将值赋给一个新的变量

范型 for(generic for)

泛型 for 循环通过一个迭代器(iterator)函数来遍历所有值:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
-- 打印数组a的所有值
local a = {"a", "b", "c", "d"}
for i, v in ipairs(a) do
print("index:", i, " value:", v)
end

-- output:
index: 1 value: a
index: 2 value: b
index: 3 value: c
index: 4 value: d

-- 打印table t中所有的key
for k in pairs(t) do
print(k)
end

函数

1
2
3
function function_name (arc)  -- arc 表示参数列表,函数的参数列表可以为空
-- body
end

Lua函数的参数大部分是按传递的,只有传入一个表table时,会进行引用传递。

参数补齐

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
local function fun1(a, b)       --两个形参,多余的实参被忽略掉
print(a, b)
end

local function fun2(a, b, c, d) --四个形参,没有被实参初始化的形参,用nil初始化
print(a, b, c, d)
end

local x = 1
local y = 2
local z = 3

fun1(x, y, z) -- z被函数fun1忽略掉了,参数变成 x, y
fun2(x, y, z) -- 后面自动加上一个nil,参数变成 x, y, z, nil

-->output
1 2
1 2 3 ni

变长参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
local function func( ... )                -- 形参为 ... ,表示函数采用变长参数

local temp = {...} -- 访问的时候也要使用 ...
local ans = table.concat(temp, " ") -- 使用 table.concat 库函数对数
-- 组内容使用 " " 拼接成字符串。
print(ans)
end

func(1, 2) -- 传递了两个参数
func(1, 2, 3, 4) -- 传递了四个参数

-->output
1 2

1 2 3 4

返回值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
local function init()       -- init 函数 返回两个值 1 和 "lua"
return 1, "lua"
end

local x, y, z = init(), 2 -- init 函数的位置不在最后,此时只返回 1
print(x, y, z) -->output 1 2 nil

local a, b, c = 2, init() -- init 函数的位置在最后,此时返回 1 和 "lua"
print(a, b, c) -->output 2 1 lua

-- 使用括号运算符

print((init()), 2) -->output 1 2
print(2, (init())) -->output 2 1

全动态函数调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
local function run(x, y)
print('run', x, y)
end

local function attack(targetId)
print('targetId', targetId)
end

local function do_action(method, ...)
local args = {...} or {}
method(unpack(args, 1, table.maxn(args)))
end

do_action(run, 1, 2) -- output: run 1 2
do_action(attack, 1111) -- output: targetId 1111

模块

my.lua

1
2
3
4
5
6
7
8
9
10
11
local foo={}

local function getname()
return "Lucy"
end

function foo.greeting()
print("hello " .. getname())
end

return foo

main.lua

1
2
local fp = require("my")
fp.greeting() -->output: hello Lucy

String库

string.byte

返回ASCII码

用该函数来进行字符串相关的扫描和分析是最为高效的

1
2
3
4
5
6
7
8
print(string.byte("abc", 1, 3))
print(string.byte("abc", 3)) -- 缺少第三个参数,第三个参数默认与第二个相同,此时为 3
print(string.byte("abc")) -- 缺少第二个和第三个参数,此时这两个参数都默认为 1

-->output
97 98 99