鍍金池/ 教程/ Java/ 表達(dá)式
定時(shí)任務(wù)
函數(shù)的參數(shù)
超時(shí)
一個(gè) openresty 內(nèi)存“泄漏”問(wèn)題
獲取 uri 參數(shù)
局部變量
sleep
灰度發(fā)布
TIME_WAIT
代碼覆蓋率
連接池
CentOS 平臺(tái)安裝
稀疏數(shù)組
如何只啟動(dòng)一個(gè) timer 工作?
變量的共享范圍
break,return 關(guān)鍵字
Nginx
SQL 注入
如何引用第三方 resty 庫(kù)
不同階段共享變量
獲取請(qǐng)求 body
動(dòng)態(tài)生成的 lua-resty-redis 模塊方法
動(dòng)態(tài)加載證書(shū)和 OCSP stapling
repeat 控制結(jié)構(gòu)
編碼為 array 還是 object
Nginx 靜態(tài)文件服務(wù)
執(zhí)行階段概念
Lua 函數(shù)
日期時(shí)間函數(shù)
健康監(jiān)測(cè)
與其他 location 配合
for 控制結(jié)構(gòu)
函數(shù)定義
HTTPS 時(shí)代
點(diǎn)號(hào)與冒號(hào)操作符的區(qū)別
String 庫(kù)
文件操作
OpenResty 最佳實(shí)踐
<code>ngx.shared.DICT</code> 非隊(duì)列性質(zhì)
使用動(dòng)態(tài) DNS 來(lái)完成 HTTP 請(qǐng)求
代碼規(guī)范
什么是 JIT?
Windows 平臺(tái)安裝
正確的記錄日志
LuaNginxModule
不用標(biāo)準(zhǔn)庫(kù)
C10K 編程
控制結(jié)構(gòu)
請(qǐng)求中斷后的處理
Lua 環(huán)境搭建
Test::Nginx 能指定現(xiàn)成的 nginx.conf,而不是自動(dòng)生成一個(gè)嗎
Lua 基礎(chǔ)數(shù)據(jù)類(lèi)型
動(dòng)態(tài)限速
PostgresNginxModule
簡(jiǎn)單API Server框架
API 測(cè)試
location 匹配規(guī)則
虛變量
單元測(cè)試
防止 SQL 注入
select + set_keepalive 組合操作引起的數(shù)據(jù)讀寫(xiě)錯(cuò)誤
阻塞操作
全動(dòng)態(tài)函數(shù)調(diào)用
Web 服務(wù)
典型應(yīng)用場(chǎng)景
Nginx 新手起步
TLS session resumption
輸出響應(yīng)體
調(diào)用代碼前先定義函數(shù)
module 是邪惡的
怎樣理解 cosocket
模塊
Socket 編程發(fā)展
如何對(duì) Nginx Lua module 添加新 api
如何在后臺(tái)開(kāi)啟輕量級(jí)線(xiàn)程完成定時(shí)任務(wù)?
如何定位問(wèn)題
table 庫(kù)
json 解析的異常捕獲
如何安裝火焰圖生成工具
lua 中如何 continue
if 是邪惡的
為什么我們的域名不能被解析
抵制使用 module() 定義模塊
測(cè)試
body 在 location 中的傳遞
Lua 入門(mén)
子查詢(xún)
pipeline 壓縮請(qǐng)求數(shù)量
如何發(fā)起新 HTTP 請(qǐng)求
Lua 簡(jiǎn)介
緩存失效風(fēng)暴
Ubuntu 平臺(tái)安裝
日志輸出
緩存
Lua 面向?qū)ο缶幊?/span>
Nginx 陷阱和常見(jiàn)錯(cuò)誤
Redis 接口的二次封裝(發(fā)布訂閱)
日志
訪(fǎng)問(wèn)有授權(quán)驗(yàn)證的 Redis
正則表達(dá)式
lock
熱裝載代碼
調(diào)用 FFI 出現(xiàn) &quot;table overflow&quot;
數(shù)據(jù)合法性檢測(cè)
禁止某些終端訪(fǎng)問(wèn)
控制結(jié)構(gòu) if-else
調(diào)試
與 Docker 使用的網(wǎng)絡(luò)瓶頸
PostgresNginxModule 模塊的調(diào)用方式
用 do-end 整理你的代碼
FFI
什么時(shí)候使用
簡(jiǎn)介
環(huán)境搭建
Mac OS X 平臺(tái)安裝
火焰圖
負(fù)載均衡
while 型控制結(jié)構(gòu)
如何定位 openresty 崩潰 bug
使用 Nginx 內(nèi)置綁定變量
判斷數(shù)組大小
請(qǐng)求返回后繼續(xù)執(zhí)行
Redis 接口的二次封裝
KeepAlive
反向代理
協(xié)議無(wú)痛升級(jí)
數(shù)學(xué)庫(kù)
元表
Vanilla 介紹
HelloWorld
LuaCjsonLibrary
持續(xù)集成
代碼靜態(tài)分析
網(wǎng)上有大量對(duì) Lua 調(diào)優(yōu)的推薦,我們應(yīng)該如何看待?
script 壓縮復(fù)雜請(qǐng)求
非空判斷
性能測(cè)試
函數(shù)返回值
API 的設(shè)計(jì)
kong 介紹
表達(dá)式
不支持事務(wù)
LuaRestyDNSLibrary 簡(jiǎn)介

表達(dá)式

算術(shù)運(yùn)算符

Lua 的算術(shù)運(yùn)算符如下表所示:

算術(shù)運(yùn)算符 說(shuō)明
+ 加法
- 減法
* 乘法
/ 除法
^ 指數(shù)
% 取模

示例代碼:test1.lua

print(1 + 2)       -->打印 3
print(5 / 10)      -->打印 0.5。 這是Lua不同于c語(yǔ)言的
print(5.0 / 10)    -->打印 0.5。 浮點(diǎn)數(shù)相除的結(jié)果是浮點(diǎn)數(shù)
-- print(10 / 0)   -->注意除數(shù)不能為0,計(jì)算的結(jié)果會(huì)出錯(cuò)
print(2 ^ 10)      -->打印 1024。 求2的10次方

local num = 1357
print(num % 2)       -->打印 1
print((num % 2) == 1) -->打印 true。 判斷num是否為奇數(shù)
print((num % 5) == 0)  -->打印 false。判斷num是否能被5整數(shù)

關(guān)系運(yùn)算符

關(guān)系運(yùn)算符 說(shuō)明
< 小于
> 大于
<= 小于等于
>= 大于等于
== 等于
~= 不等于

示例代碼:test2.lua

print(1 < 2)    -->打印 true
print(1 == 2)   -->打印 false
print(1 ~= 2)   -->打印 true
local a, b = true, false
print(a == b)  -->打印 false

注意:Lua 語(yǔ)言中“不等于”運(yùn)算符的寫(xiě)法為:~=

在使用“==”做等于判斷時(shí),要注意對(duì)于 table, userdate 和函數(shù), Lua 是作引用比較的。也就是說(shuō),只有當(dāng)兩個(gè)變量引用同一個(gè)對(duì)象時(shí),才認(rèn)為它們相等??梢钥聪旅娴睦樱?/p>

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

由于 Lua 字符串總是會(huì)被“內(nèi)化”,即相同內(nèi)容的字符串只會(huì)被保存一份,因此 Lua 字符串之間的相等性比較可以簡(jiǎn)化為其內(nèi)部存儲(chǔ)地址的比較。這意味著 Lua 字符串的相等性比較總是為 O(1). 而在其他編程語(yǔ)言中,字符串的相等性比較則通常為 O(n),即需要逐個(gè)字節(jié)(或按若干個(gè)連續(xù)字節(jié))進(jìn)行比較。

邏輯運(yùn)算符

邏輯運(yùn)算符 說(shuō)明
and 邏輯與
or 邏輯或
not 邏輯非

Lua 中的 and 和 or 是不同于 c 語(yǔ)言的。在 c 語(yǔ)言中,and 和 or 只得到兩個(gè)值 1 和 0,其中 1 表示真,0 表示假。而 Lua 中 and 的執(zhí)行過(guò)程是這樣的:

  • a and b 如果 a 為 nil,則返回 a,否則返回 b;
  • a or b 如果 a 為 nil,則返回 b,否則返回 a。

示例代碼:test3.lua

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

注意:所有邏輯操作符將 false 和 nil 視作假,其他任何值視作真,對(duì)于 and 和 or,“短路求值”,對(duì)于 not,永遠(yuǎn)只返回 true 或者 false。

字符串連接

在 Lua 中連接兩個(gè)字符串,可以使用操作符“..”(兩個(gè)點(diǎn))。如果其任意一個(gè)操作數(shù)是數(shù)字的話(huà),Lua 會(huì)將這個(gè)數(shù)字轉(zhuǎn)換成字符串。注意,連接操作符只會(huì)創(chuàng)建一個(gè)新字符串,而不會(huì)改變?cè)僮鲾?shù)。也可以使用 string 庫(kù)函數(shù) string.format 連接字符串。

print("Hello " .. "World")    -->打印 Hello World
print(0 .. 1)                 -->打印 01

str1 = string.format("%s-%s","hello","world")
print(str1)              -->打印 hello-world

str2 = string.format("%d-%s-%.2f",123,"world",1.21)
print(str2)              -->打印 123-world-1.21

由于 Lua 字符串本質(zhì)上是只讀的,因此字符串連接運(yùn)算符幾乎總會(huì)創(chuàng)建一個(gè)新的(更大的)字符串。這意味著如果有很多這樣的連接操作(比如在循環(huán)中使用 .. 來(lái)拼接最終結(jié)果),則性能損耗會(huì)非常大。在這種情況下,推薦使用 table 和 table.concat() 來(lái)進(jìn)行很多字符串的拼接,例如:

local pieces = {}
for i, elem in ipairs(my_list) do
    pieces[i] = my_process(elem)
end
local res = table.concat(pieces)

當(dāng)然,上面的例子還可以使用 LuaJIT 獨(dú)有的 table.new 來(lái)恰當(dāng)?shù)爻跏蓟?pieces 表的空間,以避免該表的動(dòng)態(tài)生長(zhǎng)。這個(gè)特性我們?cè)诤竺孢€會(huì)詳細(xì)討論。

優(yōu)先級(jí)

Lua 操作符的優(yōu)先級(jí)如下表所示(從高到低):

優(yōu)先級(jí)
^
not   # -
*   /   %
+   -
..
< > <=  >=  ==  ~=
and
or

示例:

local a, b = 1, 2
local x, y = 3, 4
local i = 10
local res = 0
res = a + i < b/2 + 1  -->等價(jià)于res =  (a + i) < ((b/2) + 1)
res = 5 + x^2*8        -->等價(jià)于res =  5 + ((x^2) * 8)
res = a < y and y <=x  -->等價(jià)于res =  (a < y) and (y <= x)

若不確定某些操作符的優(yōu)先級(jí),就應(yīng)顯示地用括號(hào)來(lái)指定運(yùn)算順序。這樣做還可以提高代碼的可讀性。