local a = true local b = 0 local c = nil if a then print("a") -->output:a else print("not a") --这个没有执行 end if b then print("b") -->output:b else print("not b") --这个没有执行 end if c then print("c") --这个没有执行 else print("not c") -->output:not c end
number
Number 类型用于表示实数,和 C/C++ 里面的 double 类型很类似
1 2 3 4
local order = 3.99 local score = 98.01 print(math.floor(order)) -->output:3 print(math.ceil(score)) -->output:99
string
Lua 中有三种方式表示字符串
使用一对匹配的单引号。例:’hello’
使用一对匹配的双引号。例:”abclua”
字符串还可以用一种长括号(即[[ ]])括起来的方式定义
我们把两个正的方括号(即[[)间插入 n 个等号定义为第 n 级正长括号。就是说,0 级正的长括号写作 [[ ,一级正的长括号写作 [=[,如此等等。反的长括号也作类似定义;举个例子,4 级反的长括号写作 ]====]。一个长字符串可以由任何一级的正的长括号开始,而由第一个碰到的同级反的长括号结束。整个词法分析过程将不受分行限制,不处理任何转义符,并且忽略掉任何不同级别的长括号。这种方式描述的字符串可以包含任何东西,当然本级别的反长括号除外。例:[[abc\nbc]],里面的 “\n” 不会被转义
local str1 = 'hello world' local str2 = "hello lua" local str3 = [["add\name",'hello']] local str4 = [=[string have a [[]].]=] print(str1) -->output:hello world print(str2) -->output:hello lua print(str3) -->output:"add\name",'hello' print(str4) -->output:string have a [[]].
table
Table 类型实现了一种抽象的“关联数组”。“关联数组”是一种具有特殊索引方式的数组,索引通常是字符串(string)或者 number 类型,但也可以是除 nil 以外的任意类型的值。
-- 由于全局变量一般会污染全局名字空间,同时也有性能损耗(即查询全局环境表的开销),因此我们应当尽量使用“局部函数”,其记法是类似的,只是开头加上 local 修饰符 localfunctionfoo(args)--args参数,函数的参数列表可以为空 print(args.." in the function") --dosomething() local x = 10 local y = 20 return x + y end local a = foo --把函数赋给变量 print(a("foo")) --output: foo in the function 30
localfunctionswap(a, b)--定义函数swap,函数内部进行交换两个变量的值 local temp = a a = b b = temp print(a, b) end local x = "hello" local y = 20 print(x, y) swap(x, y) --调用swap函数 print(x, y) --调用swap函数后,x和y的值并没有交换 -->output hello 20 20 hello hello 20
localfunctionfun1(a, b)--两个形参,多余的实参被忽略掉 print(a, b) end localfunctionfun2(a, b, c, d)--四个形参,没有被实参初始化的形参,用nil初始化 print(a, b, c, d) end local x = 1 local y = 2 local z = 3 fun1(x, y, z) -- z被函数fun1忽略掉了,参数变成 x, y fun2(x, y, z) -- 后面自动加上一个nil,参数变成 x, y, z, nil -->output 12 123nil
local s, e = string.find("hello world", "llo") print(s, e) -->output 3 5
1 2 3 4 5 6 7
localfunctionswap(a, b)-- 定义函数 swap,实现两个变量交换值 return b, a -- 按相反顺序返回变量的值 end local x = 1 local y = 20 x, y = swap(x, y) -- 调用 swap 函数 print(x, y) --> output 20 1
local a = { x = 1, y = 0} local b = { x = 1, y = 0} if a == b then print("a==b") else print("a~=b") end ---output: a~=b
逻辑运算符
逻辑运算符
说明
and
逻辑与
or
逻辑或
not
逻辑非
1 2 3 4 5 6 7 8 9 10
local c = nil local d = 0 local e = 100 print(c and d) -->打印 nil print(c and e) -->打印 nil print(d and e) -->打印 100 print(c or d) -->打印 0 print(c or e) -->打印 100 print(not c) -->打印 true print(not d) -->打印 false
local pieces = {} for i, elem inipairs(my_list) do pieces[i] = my_process(elem) end local res = table.concat(pieces)
优先级
优先级如下表所示(从高到低)
优先级
^
not # -
* / %
+ -
..
< > <= >= == ~=
and
or
1 2 3 4 5 6 7
local a, b = 1, 2 local x, y = 3, 4 local i = 10 local res = 0 res = a + i < b/2 + 1-->等价于res = (a + i) < ((b/2) + 1) res = 5 + x^2*8-->等价于res = 5 + ((x^2) * 8) res = a < y and y <=x -->等价于res = (a < y) and (y <= x)
结构控制
if/else
1 2 3 4 5 6 7 8 9 10 11 12
score = 0 if score == 100then print("Very good!Your score is 100") elseif score >= 60then print("Congratulations, you have passed it,your score greater or equal to 60") else if score > 0then print("Your score is better than 0") else print("My God, your score turned out to be 0") end--与上一示例代码不同的是,此处要添加一个end end
while
1 2 3 4 5 6 7
x = 1 sum = 0 while x <= 5do sum = sum + x x = x + 1 end print(sum) -->output 15
local t = {1, 3, 5, 8, 11, 18, 21} local i for i, v inipairs(t) do if11 == v then print("index[" .. i .. "] have right value[11]") break end end
repeat
类似于do-while
1 2 3 4
x = 10 repeat print(x) untilfalse-- 死循环
for
for 数字型
1 2 3
for var = begin, finish, step do --body end
+ var 从 begin 变化到 finish,每次变化都以 step 作为步长递增 var + begin、finish、step 三个表达式只会在循环开始时执行一次 + 第三个表达式 step 是可选的,默认为 1 + 控制变量 var 的作用域仅在 for 循环内,需要在外面控制,则需将值赋给一个新的变量 + 循环过程中不要改变控制变量的值,那样会带来不可预知的影响
1 2 3 4 5 6 7 8 9
for i = 1, 5do print(i) end -- output: 1 2 3 4 5
1 2 3 4 5 6 7 8 9
for i = 1, 10, 2do print(i) end -- output: 1 3 5 7 9
1 2 3 4
for i = 10, 1, -1do print(i) end -- output : ?
for 泛型
1 2 3 4 5 6 7 8 9
local a = {"a", "b", "c", "d"} for i, v inipairs(a) do print("index:", i, " value:", v) end -- output: index: 1 value: a index: 2 value: b index: 3 value: c index: 4 value: d
-- 计算最小的x,使从1到x的所有数相加和大于100 sum = 0 i = 1 whiletruedo sum = sum + i if sum > 100then break end i = i + 1 end print("The result is " .. i) -->output:The result is 14
location /print_param { content_by_lua_block { local arg = ngx.req.get_uri_args() for k,v in pairs(arg) do ngx.say("[GET ] key:", k, " v:", v) end ngx.req.read_body() -- 解析 body 参数之前一定要先读取 body local arg = ngx.req.get_post_args() for k,v in pairs(arg) do ngx.say("[POST] key:", k, " v:", v) end } }
location /test { content_by_lua_block { -- ngx.var.limit_rate = 1024*1024 local file, err = io.open(ngx.config.prefix() .. "data.db","r") if not file then ngx.log(ngx.ERR, "open file error:", err) ngx.exit(ngx.HTTP_SERVICE_UNAVAILABLE) end local data while true do data = file:read(1024) if nil == data then break end ngx.print(data) ngx.flush(true) end file:close() } }
按块读取本地文件内容(每次 1KB),并以流式方式进行响应。
日志输出
1 2 3 4 5
content_by_lua_block { ngx.log(ngx.ERR, "this is err") ngx.log(ngx.INFO, "this is info") ngx.log(ngx.DEBUG, "this is debug") }
location /check { alias /lvm/client-detection/; index index.html; expires5d; } location = /testmethod { add_header Access-Control-Allow-Origin $http_origin; add_header Access-Control-Allow-Credentials "true"; add_header'Access-Control-Allow-Methods''GET,PUT, POST, OPTIONS, DELETE'; default_type"application/json; charset=utf-8"; content_by_lua_file testmethod.lua; proxy_redirectoff; } location = /getdomains { add_header Access-Control-Allow-Origin $http_origin; add_header Access-Control-Allow-Credentials "true"; add_header'Access-Control-Allow-Methods''GET,PUT, POST, OPTIONS, DELETE'; default_type"application/json; charset=utf-8"; content_by_lua' local mainHost = {"www.qlteacher.com","zone.qlteacher.com","player.qlteacher.com","yanxiu.qlteacher.com","id.qlteacher.com","blog.qlteacher.com"} local cjson = require("cjson") ngx.say(cjson.encode(mainHost)) '; }
1 2 3 4 5 6 7 8 9 10 11 12 13
local cjson = require("cjson") if ngx.req.get_method() == "OPTIONS" then ngx.exit(204) end local t = {time = ngx.time(),method = ngx.req.get_method()} t.urlargs = ngx.req.get_uri_args() ngx.req.read_body() local postargs = ngx.req.get_post_args() if postargs then t.postargs = postargs end t.host = ngx.req.get_headers()["Host"] ngx.say(cjson.encode(t))
local online = require("online") local handler function handler(premature,domain,uri,userInfo) --ngx.log(ngx.ERR,"domain=",domain) --ngx.log(ngx.ERR,"uri=",uri) --ngx.log(ngx.ERR,"userInfo=",userInfo) online.broadcast(premature,domain,uri,userInfo) end local ok, err = ngx.timer.at(0, handler,tostring(ngx.var.HTTP_HOST),tostring(ngx.var.uri),ngx.var.cookie_userInfo) if not ok then ngx.log(ngx.ERR, "onlineCount error", err) end
local redis = require "resty.redis" local ResourceTemplate = {} function ResourceTemplate:new(o) o = o or {} setmetatable(o,self) self.__index = self return o end function ResourceTemplate:dealWith(callback) local r = self:open() if not r then error("No resource opened") end local ok, data = pcall(callback,r) self:close(r) if not ok then error(data) else return data end end local RedisTemplate = ResourceTemplate:new({ open = function(self) local red = redis:new() red:set_timeout(1000) -- local ips = {{host="10.0.0.246",port=6379},{host="10.0.0.247",port=6379}} -- math.randomseed( tonumber(tostring(os.time()):reverse():sub(1,6)) ) -- local ip = ips[math.random(2)] -- local ok, err = red:connect(ip.host, ip.port,{ pool = "my_redis_cluster" }) local ok, err = red:connect("10.0.0.220", 6379) if not ok then error("failed to connect: "..err) end return red end, close = function(self, red) local ok, err = red:set_keepalive(10000, 100) if not ok then error("failed to set keepalive: "..err) end end }) return { ResourceTemplate = ResourceTemplate, RedisTemplate = RedisTemplate }
local SID_PERFIX ="sid:" local UID_PERFIX ="uid:" local VID_PERFIX ="vid:" local PV_PREFIX ="pv:" local mainHost = {"id.thpower.com"} local cjson = require("cjson") local Resource = require("resource") local DecodeCookie = require("decode_cookie") local redis = Resource.RedisTemplate local Online = {} function Online:broadcast(domain,uri,userInfo) --判断请求地址是否记录 local address = "www.thpower.com" for key,value in pairs(mainHost) do if string.find(domain..uri,value.."*") then address = value end end local cookie = DecodeCookie:new({token=userInfo}) local userid local userkey if cookie:isValid() then --登陆用户 local currentUser = cookie:currentUser() local index = string.find(currentUser,"@") userid = string.sub(currentUser,0,index-1) userkey = UID_PERFIX..userid else -- 未登录用户记录 userid = userInfo userkey = SID_PERFIX..userid end redis:dealWith(function(red) --red:init_pipeline() red:incr(PV_PREFIX..address) red:expire(PV_PREFIX..address,120) red:set(VID_PERFIX..address..":"..userid,"","EX",120,"NX") red:set(userkey,userid,"EX",1800) --red:commit_pipeline() end) end return Online
local cjson = require("cjson") --local Resource = require("redisCl") --local redis = Resource.RedisTemplate local Resource = require("resource") local redis = Resource.RedisTemplate ngx.header.content_type = "application/json; charset=utf-8" local domain = ngx.var.arg_domain local _max = ngx.var.arg_max local _min = ngx.var.arg_min if domain == nil then ngx.say("错误的请求") return end if _max == nil then _max=1440 end if _min == nil then _min=0 end redis:dealWith(function(red) local view,err = red:lrange("OnLine:"..domain,_min,_max) local list = {} for key, value in pairs(view) do local item = cjson.decode(value) --ngx.say(item.count) table.insert(list,item) end ngx.say(cjson.encode(list)) end)