lua基础语法篇一
Posted bushrose
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了lua基础语法篇一相关的知识,希望对你有一定的参考价值。
打印
print("hello world")
注释
- 单行注释
- 多行注释
-- 这是单行注释
--[[
这是多行注释
]]
赋值
s="Hello World"
-- 多重赋值
a,b="String a","String b"
-- 交换值,类似python
a,b="String a","String b"
a,b=b,a
数据类型
Lua有8种基本类型,如下表
类型 | 说明 |
---|---|
nil | 空值,只包含一个nil |
boolean | 布尔类型 |
number | 数值类型 |
string | 字符串,用单引号或双引号表示 |
table | Lua中的表,其实是一个关联数组,数组的索引可以是数字、字符串或表类型 |
function | 函数,由C或Lua编写的函数 |
userdata | 表示存储在变量中的c数据结构 |
thread | 线程类型,表示执行的独立线路,用于执行协同程序 |
print(type("Hello world")) --> string
print(type(10.4*3)) --> number
print(type(print)) --> function
print(type(type)) --> function
print(type(true)) --> boolean
print(type(nil)) --> nil
print(type()) --> table
print(type(io.stdin)) --> userdata
nil(空)
nil表示一种没有任何有效值
print(type(a))
给全局变量和table中某一变量赋值为nil,等同于删除掉。
boolean(布尔)
- boolean类型只有两个可选值,
true
(真)和false
(假)。 - 在Lua中,
false
和nil
是假,其他的都为真。
number(数字)
Lua默认只有一种number类型,类似C语言中的double(双精度)
string(字符串)
字符串由一对双引号或单引号表示。
-- 字符串有以下四种表示方式
s=\'string\'
s="String"
s=[[String]]
s=[==[String]==]
字符串连接采用..
操作符
print("a".."b")
-- ab
使用#
放在字符串前面来计算其长度,如下:
s="Hello world"
print(#s)
--11
table(表)
-- 创建一个空的表
local tb=
-- 初始化表
local tb1="a","b","c"
- 不同于其他语言,Lua的索引从1开始
- table不会固定大小,新增数据table长度自动增加,没初始化的table都是nil
function(函数)
在 Lua 中,函数是被看作是"第一类值(First-Class Value)",函数可以存在变量里:
function factorial1(n)
if n == 0 then
return 1
else
return n * factorial1(n - 1)
end
end
print(factorial1(5))
factorial2 = factorial1
print(factorial2(5))
function 可以以匿名函数(anonymous function)的方式通过参数传递:
function anonymous(tab, fun)
for k, v in pairs(tab) do
print(fun(k, v))
end
end
tab = key1 = "val1", key2 = "val2"
anonymous(tab, function(key, val)
return key .. " = " .. val
end)
thread(线程)
在 Lua 里,最主要的线程是协同程序(coroutine)。它跟线程(thread)差不多,
拥有自己独立的栈、局部变量和指令指针,可以跟其他协同程序共享全局变量和其他大部分东西。
线程跟协程的区别:线程可以同时多个运行,而协程任意时刻只能运行一个,
并且处于运行状态的协程只有被挂起(suspend)时才会暂停。
userdata(自定义类型)
userdata 是一种用户自定义数据,用于表示一种由应用程序或 C/C++ 语言库所创建的类型,
可以将任意 C/C++ 的任意数据类型的数据(通常是 struct 和 指针)存储到 Lua 变量中调用。
变量
Lua 变量有三种类型:
- 全局变量默认情况下,Lua中所有的变量都是全局变量
- 局部变量使用local显式声明在函数内的变量,以及函数的参数,都是局部变量。在函数外即使用local去声明,它的作用域也是当前的整个文件,这相当于一个全局变量。
- 表中的域
注意,变量的默认值均为nil。Lua语言不区分未初始化变量和被赋值为nil的变量,因此全局变量无须声明即可使用。「在Lua中,应尽可能使用局部变量」,这有两个好处:
- 避免命名冲突
- 访问局部变量的速度比全局变量更快
a = 5 -- 全局变量
local b = 5 -- 局部变量
function joke()
c = 5 -- 全局变量
local d = 6 -- 局部变量
end
a, b, c = 0, 2, 7 -- Lua支持多变量赋值
本文由【产品经理不是经理】gzh同步发布,欢迎关注
Lua基础语法学习
学习链接
- https://blog.csdn.net/jiangwei0512/article/details/51057649
- https://blog.csdn.net/THIOUSTHIOUS/article/details/86552762
- https://segmentfault.com/a/1190000018641801
- https://cloud.tencent.com/developer/article/1043931
- 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、表达式
- ~=相当于c语言里面的!=,不等于。
- table、userdata和function是引用比较,只有两个变量指向同一个对象才是相等。
- 逻辑运算符是"and or not",但是这里的and和or意思跟c语言有不同:
a and b:如果a为false,则返回a,否则返回b;
a or b :如果a为true,则返回a,否则返回b。 - “…”两个点,表示字符连接符;如果操作数是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
访问权限检查提交阶段;
(9)try-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基础语法篇一的主要内容,如果未能解决你的问题,请参考以下文章