Lua基础语法学习

Posted 果子哥丶

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Lua基础语法学习相关的知识,希望对你有一定的参考价值。

学习链接

  1. https://blog.csdn.net/jiangwei0512/article/details/51057649
  2. https://blog.csdn.net/THIOUSTHIOUS/article/details/86552762
  3. https://segmentfault.com/a/1190000018641801
  4. https://cloud.tencent.com/developer/article/1043931
  5. https://github.com/openresty/lua-nginx-module

1、注释

Lua使用的注释如下:

-- 单行注释使用
--[[
    多行注释使用
    多行注释使用
]]


--[[
if x > 1 then
    -- 注释1
else
    -- 注释2
end
--]]

2、数据类型

Lua的8个基本类型:

几点说明:

  • nil类型只有nil这么一个值
  • boolean有两个值true和false。另外Lua中的所有值都可以用在条件语句中,且除了false和nil表示假,其它都表示真。比如0,它表示真。
  • 数值类型只有number,没有int、float等类型。
  • string可以用双引号,也可以用单引号指定。还可以用[[里面是字符串]],[[]]的特点是可以包含多行,可以嵌套,且不解释转移字符。
  • function和其他上述的类型一样,属于第一类值,就是说也可以存在普通的变量里面。
  • table、userdata和thread后面还会讲。

3、table库

do
    --> table.concat  连接 函数

    tab = {"a", "c", "d", "b"}

    --(1)
    -- 一个参数,参数为 表(tab),作用为连接 tab 中所有的 value
    print(table.concat(tab))   
    --> 输出结果: acdb

    --(2)
    -- 两个参数,参数一:表(tab),参数二:分隔符(nil)-- 作用为连接tab中所有的value,value 间以 nil 隔开
    print(table.concat(tab, nil))  
    --> 输出结果: acdb

    --(3)
    -- 三个参数,参数一:表(tab),参数二:分隔符 (" @@ ")-- 参数三:起始位置(2),作用为连接tab中所有的value,位置是从1开始算的
    -- value 间以 " @@ " 隔开, 从 tab 的第二个value开始连接,
    -- 到 tab 的 end 
    print(table.concat(tab, " @@ ", 2))  
    --> 输出结果: c @@ d @@ b

    --(4)
    -- 四个参数,参数一:表(tab),参数二:分隔符 (" - ")-- 参数三:起始位置(2),参数四:结束连接位置,作用为连
    -- 接tab中所有的value,value 间以 " - " 隔开, 从 tab 
    -- 的第二个value  开始连接,到 tab 的 第 3 个 value结束连接

    print( table.concat(tab, " - ", 2, 3))  
    --> 输出结果: c - d
    print(table.concat(tab, " ## \\n", 2, 4))   
    --> 输出结果:
    --> c ##
    --> d ##
    --> b

    --(5)
    for i,v in ipairs(tab) do
        print(i,v)
    end
    --> 输出结果:
    -- 1      a
    -- 2      c
    -- 3      d
    -- 4      b

    -- 说明 table.concat 不会改变 原始 table 即(tab) 的结构
end

4、表达式

  1. ~=相当于c语言里面的!=,不等于。
  2. table、userdata和function是引用比较,只有两个变量指向同一个对象才是相等。
  3. 逻辑运算符是"and or not",但是这里的and和or意思跟c语言有不同:
    a and b:如果a为false,则返回a,否则返回b;
    a or b :如果a为true,则返回a,否则返回b。
  4. “…”两个点,表示字符连接符;如果操作数是number,则转换为字符串:

print(1 … 2) --> 12,注意…前后需要有空格,否则会报错
注意这里1 …之间有一个空格,不然会报错。
但是如果是字符串就不需要:

print("hello".."world")	--> helloworld

5、表的构造

下面是基本例子:

table1 = {}                             --> 空表
names = {"jack", "john", "jimmy"}       --> 列表形式初始化
print(names[1])                         --> jack,下标从1开始
names[4] = "jason"                      --> 动态添加
print(names[4])                         --> jason
print(names[5])                         --> nil,因为不存在
a = {x = 0, y = 1}                      --> record形式初始化
print(a.x)                              --> 0
print(a["x"])                           --> 0,另一种表示方式
b = {"helloworld", x = 1, "goodbye"}    -->混合形式
print(b[1])                             --> helloworld
print(b.x)                              --> 1
print(b[2])                             --> goodbye
-- print(b.1)                           --> 没有这种

表中分隔可以使用逗号,也可以使用分号。
还有一种更一般的形式:

a = {["+"] = "add", ["-"] = "sub", ["*"] = "mul", ["/"] = "div", }  --> 后面可以有逗号
print(a["+"])   --> add
b = {[1] = "one", [2] = "two", [3] = "three"}
print(b[1])     --> one

6、控制语句

IF语句

if xxx then xxx end
if xxx then xxx else xxx end
if xxx then xxx elseif xxx then xxx else xxx end

elseif可以有很多个,注意else和if中间没有空格!!

WHILE语句

while xxx do xxx end

REPEAT-UNTIL语句

repeat xxx until xxx

FOR语句

for var=exp1,exp2,exp3 do xxx end

这里for里面的语句意思是var以exp3为step,从exp1到exp2。

需要注意几点:

  • 几个exp只会运行一次,且在for循环之前;
  • var是局部变量;
  • 循环过程中不要改变var。
for x,y,z in xxx do xxx end

BREAK和RETURN语句
break退出当前循环;return退出函数并返回结果。
注意break和return只能用在一个block的结尾。如果有时候确实想要在另外的地方使用,可以用这样的方式:

do break/return end

7、函数

函数的定义:

function funcName (args)
    states
end

关于函数调用时,如果没有参数,需要使用();

如果参数是字符串或者表构造时,可以不用()。

Lua函数中实参和形参的匹配也比较不讲究,实参多于形参,多余部分会忽略;实参少于形参,少的形参会是nil。这个与多变量赋值方式一致。

函数可以返回多个值:

function func (void)
    return 1,2
end
 
a,b = func()
print(a)    --> 1
print(b)    --> 2

通过()可以是函数强制返回一个值:

function func (void)
    return 1,2
end
 
print(func())       --> 1 2
print((func()))     --> 1

Lua可以有可变参数。使用…三个点表示,在函数中用一个叫arg的table表示参数,arg中还有一个域n表示参数的个数。
下面是一个例子:

function func_1(...)
    print("The number of args: " .. #{...})
    for i,v in ipairs({...}) do
        print(i,v)
    end
end
func_1(0, 1, 2, 3)

打印的结果是:

The number of args: 4
1       0
2       1
3       2
4       3

Lua与nginx

当 Nginx 标准模块和配置不能灵活地适应系统要求时,就可以考虑使用 Lua 扩展和定制 Nginx 服务。OpenResty 集成了大量精良的 Lua 库、第三方模块,可以方便地搭建能够处理超高并发、扩展性极高的 Web 服务,所以这里选择 OpenResty 提供的 lua-nginx-module 方案。

lua-nginx-module 模块中已经为 Lua 提供了丰富的 Nginx 调用 API,每个 API 都有各自的作用环境,详细描述见 Nginx API for Lua。这里只列举基本 API 的使用 。

先配一个 Lua 脚本服务,配置文件如下:

location ~ /lua_api {  
    # 示例用的Nginx变量  
    set $name $host;
    default_type "text/html";  
    # 通过Lua文件进行内容处理
    content_by_lua_file /home/www/nginx-api.lua;  
}

content_by_lua_file :在于指定的文件<path-to-lua-script-file>包含 Lua 代码

Nginx处理顺序阶段

1)post-read
读取请求内容阶段,nginx读取并解析完请求头之后就立即开始运行;

(2)server-rewrite
server请求地址重写阶段;

(3)find-config
配置查找阶段,用来完成当前请求与location配重块之间的配对工作;

(4)rewrite
location请求地址重写阶段,当ngx_rewrite指令用于location中,就是再这个阶段运行的;

(5)post-rewrite
请求地址重写提交阶段,当nginx完成rewrite阶段所要求的内部跳转动作,如果rewrite阶段有这个要求的话;

(6)preaccess
访问权限检查准备阶段,ngx_limit_req和ngx_limit_zone在这个阶段运行,ngx_limit_req可以控制请求的访问频率,ngx_limit_zone可以控制访问的并发度;

(7)access
权限检查阶段,ngx_access在这个阶段运行,配置指令多是执行访问控制相关的任务,如检查用户的访问权限,检查用户的来源IP是否合法;

(8)post-access
访问权限检查提交阶段;

(9try-files
配置项try_files处理阶段;

(10)content
内容产生阶段,是所有请求处理阶段中最为重要的阶段,因为这个阶段的指令通常是用来生成HTTP响应内容的;

(11)log

日志模块处理阶段;

ngx_lua 运行指令

ngx_lua属于nginx的一部分,它的执行指令都包含在nginx的11个步骤之中了,相应的处理阶段可以做插入式处理,即可插拔式架构,不过ngx_lua并不是所有阶段都会运行的;另外指令可以在http、server、server if、location、location if几个范围进行配置:

以上是关于Lua基础语法学习的主要内容,如果未能解决你的问题,请参考以下文章

lua 触动精灵基础语法

Lua 语法基础 | Nmap 脚本

自学成菜-流水账学习法lua入门

Lua基础语法讲解

lua学习之类型与值篇

Lua学习六----------Lua流程控制