一、安卓
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倍