LUA教程
一、安卓
windows
下载 安装
安装后路径在:C:\Program Files (x86)\Lua\5.1\lua.exe 打开会进入终端,和python差不多
执行方式 lua test.lua
Pycharm 安装
Settings-plugins- 搜索 lua 安装,重启
配置执行路径:
Settings-Languages-Lua-加号-设置为default,eecutable设置为C:\Program Files (x86)\Lua\5.1\lua.exe
一、基本语法
注释
单行注释(两个减号):
-- 注释
多行注释(两个减号+中括号):
--[[
fefe
]]
全局变量
lua 全部都是全局变量,如果访问一个没有定义的全局变量,返回nil
二、数据类型
数据类型
lua是动态语言
有8个基本类型
- nil 空
- boolean false和true
- string 字符串 单引号或双引号
- number 数字
- function 函数
- userdata c数据结构
- thread 独立线路,用于执行协同程序
- table 关联数据,索引可以是数字,字符串和表类型
print(type(nil))
print(type(false))
print(type("string"))
print(type(12))
print(type(type))
表
t={} #定义空表
t[0]=1 #写入,索引可以是数字或者字符串
t["k"]=2
print(t[0]) # 读取
print(t["k"])
print(t.k) # 如果key是字符串,也可以这样访问
t2={1,2,3,4 } # 定义一个数组
print(t2[1]) #读取,下标从1开始,而不是0
print(t)
函数
用function....end定义一个函数
function f1(p1,p2)
t={2,3}
print(t[1])
print(p1)
print(p2)
end
f1(1,2)
三、变量
lua中全部变量是全局变量,如果定义前加local,变为局部变量
a=1
b=2
c=3
function f1()
local d=4
e=5
a=11
print(a)
print(b)
print(c)
print(d)
end
f1()
print(a) -- a是11
print(b)
print(c)
print(d) -- 读不了d
print(e) -- 可以读e
四、循环
while
t=1
while t<10 do
print(t)
t=t+1
end
for
数值for循环
for var=exp1,exp2,exp3 do
<执行体>
end
和c的for一样,exp3是可选,默认1
for i=1,10,2 do
print(i)
end
泛型for循环
t={'key1','key2'}
for i,v in ipairs(t) do
print(i,v)
end
- i是下标,从1开始
- v是数组的值
- 如果下标和key都遍历,ipairs改为
repeat until
t=1
repeat
print(t)
t=t+1
until (t>9)
流程控制
t=1
-- if结构
if (t==1)
then
print(t,">1")
end
-- if else 结构
if (t>1)
then
print(t,">1")
else
print(t,"<=1")
end
-- if elif else 结构
if (t>1)
then
print(t,">1")
elseif (t==1)
then
print(t,"=1")
else
print(t,"<1")
end
- if 和 elseif后面都要加then,else不用,后面加end
函数
optional_function_scope function function_name( argument1, argument2, argument3..., argumentn)
function_body
return result_params_comma_separated
end
- optional_function_scope 表示函数是全局的还是局部的变量。如果局部,加local
- function_name 函数名
- argument1 函数入参
- result_params_comma_separated 函数出参,可以多值
例子:
function f1(p)
return p+1
end
print(f1(2))
多返回值例子:
function f2(p)
return p+1,p+2
end
a,b=f2(2)
print(a)
print(b)
可变入参例子:
function f3(...)
local args = { ... }
print(select("#",...)) -- 查看参数个数
a=select(1,...) -- 也可以这样读取第n个参数
print(a)
print(args[1])
print(args[2])
end
f3(10, 11, 12)
- 定义函数时,入参设置为...,然后转换...为表,最好定义为局部变量
运算符
算术运算符
-
-
-
- / % ^ -
-
-
关系运算符
- ==
- ~= 不等于
- <
-
=
- <=
逻辑运算符
- and
- or
- not
一元运算符
- .. 连接两个字符串
-
返回字符串长度
字符串
定义
- 单引号
- 双引号
- [[]]之间
字符串操作
print(string.upper('aaa')) --转换大写
print(string.lower('BBB')) --转换小写
print(string.gsub('abc', 'a', '2', 3)) --替换
print(string.find('abc', 'a')) --找字符
print(string.reverse('abc')) --反转
print(string.format('aaa:%s', 4)) --格式化字符串
print(string.len('aaa:%s')) --字符串长度
print(string.gmatch("Hello Lua user", "%a+")) --返回迭代器,返回所有查找到的自传
print(string.match("I have 2 questions for you.", "%d+ %a+")) --全匹配
print(string.sub("I have 2 questions for you.", 0, 1)) --截取
表
操作
t={1,2,3,4}
print(table.concat(t,',')) --数组转换为字符串
table.insert(t,2,6)-- 插入
t[6]=11
print(table.maxn(t)) --最大的key
table.remove(t,1) --移除 pos参数默认最后一位
print(table.sort(t)) --排序
模块
module.lua
module={}
module.param='a'
function module.func1()
print('module.func1')
end
function func3()
print('module.func1')
end
return module
1.lua
require('module')
module.func1()
print(module.param)
找包的顺序
- lua的执行程序目录,即C:\Program Files (x86)\Lua\5.1\lua\
- 环境变量 LUA_PATH
export LUA_PATH="~/lua/?.lua;;"
网络
如果报错:no resolver defined to resolve
在nginx的http里面加配置:resolver 8.8.8.8;
local httpc = http.new()
local url='http://www.kugou.com'
local res,err=httpc:request_uri(url,{
method='GET', --请求方法
body="", --请求体
headers={ -- 请求头
['Content-Type']="application/json"
}
})
ngx.log(ngx.ERR,tostring(err)) --错误信息
ngx.log(ngx.ERR,tostring(res.status))-- http状态码
ngx.log(ngx.ERR,tostring(res.body)) -- body 字符串
ngx.log(ngx.ERR,tostring(res.headers)) -- 返回头 table
其他操作
赋值
or 赋值
or 赋值和Python类似,但是0不属于nil,如果a=nil 或者false 会取后面的值
local a=nil or 0 or 1 -- a=0
local a=0 or nil or 1 -- a=0
and or
a = nil
b = a == nil and 1 or 2 -- 1
b = a ~= nil and 1 or 2 -- 2
print(b)
_G
_G类似python的globals,保存全部的全局变量
a = 1
print(_G.a)
table.foreach
类似python的map。f不能return 不然foreach就会
function f(index, value)
print(index)
print(value)
end
table.foreach(t, f)
table.foreach(t, print)
继承
lua没有类的概念,只能通过表来实现类。
而怎么实现类的继承呢?
t1 = {
a = 1
}
t2 = {
b = 2
}
t1.__index = t1
setmetatable(t2, t1)
print(t2.a)
- t1是否父类,t2是子类,要实现t2继承t1,可以这样做
- 设置t1的元表属性为自身
- 设置t1为t2的元表
- 当访问t2的a属性
- 先查看t2是否有a属性,发现没有
- 查看t2是否有元表,发现有,是t1
- 这时不是直接访问t1的a变量,而是访问t1的__index,发现非空
- 访问__index.a得到1,所以t2.a=1
如果只想查看t2是否有a属性,不需要管元表,可以使用rawget(t2,'a')
rediscluster库学习
- rediscluster的底层是redis,redis的底层是tcp。ngx.tcp文档:文档
- 通过init(),会初始化实例,包括:
- 设置cmd,为自动执行do_cmd函数
- 设置cluster命令
- 设置asking命令
- 通过new_cluster函数,生成一个客户端单例实例,保存在rediscluster.__cluster,
-
继承rediscluster的_M
-
里面有2个属性:
- config 就是new_clusterr的入参conf
- cluster 就是 通过cluster_new 函数生成的实例,继承rediscluster._cluster(注意_cluster和__cluster不一样)。初始化时会执行_cluster.Update更新曹位
-
- 当执行例如get
- 执行_cmd_exce函数
- 通过key计算槽位
- 通过槽位找到对应的ip和port
- 实例化一个redis实例,并设置ip和port
- 和对应的ip port建立tcp连接
- redis实例执行命令,获得返回值
- 通过setkeepalive,让tcp连接返回连接池
lua_code_cache off; 参数
当设置了该参数,nginx不会缓存lua代码和变量(_M和单例等),也就是每次请求都是一个全新的请求,包括redis的槽位,_M设置的变量都需要重新设置。
性能测试
Python:
start=time.time()
s=0
for i in xrange(100000000):
s=s+i
print s
print time.time()-start
4999999950000000
11.1540000439
Lua:
local socket = require "socket"
local start=socket.gettime()
local s=0
for i=1,100000000 do
s=s+i
end
print(s)
print(socket.gettime()-start)
5.00000005e+015
0.91710901260376
lua的计算性能是python的10倍