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)

找包的順序

  1. lua的執行程序目錄,即C:\Program Files (x86)\Lua\5.1\lua\
  2. 環境變量 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倍


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM