鍍金池/ 教程/ Java/ Lua 基礎(chǔ)數(shù)據(jù)類型
定時(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ù)類型
動(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í)線程完成定時(shí)任務(wù)?
如何定位問(wèn)題
table 庫(kù)
json 解析的異常捕獲
如何安裝火焰圖生成工具
lua 中如何 continue
if 是邪惡的
為什么我們的域名不能被解析
抵制使用 module() 定義模塊
測(cè)試
body 在 location 中的傳遞
Lua 入門
子查詢
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ā)布訂閱)
日志
訪問(wèn)有授權(quán)驗(yàn)證的 Redis
正則表達(dá)式
lock
熱裝載代碼
調(diào)用 FFI 出現(xiàn) &quot;table overflow&quot;
數(shù)據(jù)合法性檢測(cè)
禁止某些終端訪問(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)介

Lua 基礎(chǔ)數(shù)據(jù)類型

函數(shù) type 能夠返回一個(gè)值或一個(gè)變量所屬的類型。

print(type("hello world")) -->output:string
print(type(print))         -->output:function
print(type(true))          -->output:boolean
print(type(360.0))         -->output:number
print(type(nil))           -->output:nil

nil(空)

nil 是一種類型,Lua 將 nil 用于表示“無(wú)效值”。一個(gè)變量在第一次賦值前的默認(rèn)值是 nil,將 nil 賦予給一個(gè)全局變量就等同于刪除它。

local num
print(num)        -->output:nil

num = 100
print(num)        -->output:100

值得一提的是,OpenResty 的 Lua 接口還提供了一種特殊的空值,即 ngx.null,用來(lái)表示不同于 nil 的“空值”。后面在討論 OpenResty 的 Redis 庫(kù)的時(shí)候,我們還會(huì)遇到它。

boolean(布爾)

布爾類型,可選值 true/false;Lua 中 nil 和 false 為“假”,其它所有值均為“真”。比如 0 和空字符串就是“真”;C 或者 Perl 程序員或許會(huì)對(duì)此感到驚訝。

local a = true
local b = 0
local c = nil
if a then
    print("a")        -->output:a
else
    print("not a")    --這個(gè)沒(méi)有執(zhí)行
end

if b then
    print("b")        -->output:b
else
    print("not b")    --這個(gè)沒(méi)有執(zhí)行
end

if c then
    print("c")        --這個(gè)沒(méi)有執(zhí)行
else
    print("not c")    -->output:not c
end

number(數(shù)字)

Number 類型用于表示實(shí)數(shù),和 C/C++ 里面的 double 類型很類似??梢允褂脭?shù)學(xué)函數(shù) math.floor(向下取整)和 math.ceil(向上取整)進(jìn)行取整操作。

local order = 3.99
local score = 98.01
print(math.floor(order))   -->output:3
print(math.ceil(score))    -->output:99

一般地,Lua 的 number 類型就是用雙精度浮點(diǎn)數(shù)來(lái)實(shí)現(xiàn)的。值得一提的是,LuaJIT 支持所謂的“dual-number”(雙數(shù))模式,即 LuaJIT 會(huì)根據(jù)上下文用整型來(lái)存儲(chǔ)整數(shù),而用雙精度浮點(diǎn)數(shù)來(lái)存放浮點(diǎn)數(shù)。

另外,LuaJIT 還支持“長(zhǎng)長(zhǎng)整型”的大整數(shù)(在 x86_64 體系結(jié)構(gòu)上則是 64 位整數(shù))。例如

print(9223372036854775807LL - 1)  -->output:9223372036854775806LL

string(字符串)

Lua 中有三種方式表示字符串:

1、使用一對(duì)匹配的單引號(hào)。例:'hello'。

2、使用一對(duì)匹配的雙引號(hào)。例:"abclua"。

3、字符串還可以用一種長(zhǎng)括號(hào)(即[[ ]])括起來(lái)的方式定義。我們把兩個(gè)正的方括號(hào)(即[[)間插入 n 個(gè)等號(hào)定義為第 n 級(jí)正長(zhǎng)括號(hào)。就是說(shuō),0 級(jí)正的長(zhǎng)括號(hào)寫(xiě)作 [[ ,一級(jí)正的長(zhǎng)括號(hào)寫(xiě)作 [=[,如此等等。反的長(zhǎng)括號(hào)也作類似定義;舉個(gè)例子,4 級(jí)反的長(zhǎng)括號(hào)寫(xiě)作 ]====]。一個(gè)長(zhǎng)字符串可以由任何一級(jí)的正的長(zhǎng)括號(hào)開(kāi)始,而由第一個(gè)碰到的同級(jí)反的長(zhǎng)括號(hào)結(jié)束。整個(gè)詞法分析過(guò)程將不受分行限制,不處理任何轉(zhuǎn)義符,并且忽略掉任何不同級(jí)別的長(zhǎng)括號(hào)。這種方式描述的字符串可以包含任何東西,當(dāng)然本級(jí)別的反長(zhǎng)括號(hào)除外。例:[[abc\nbc]],里面的 "\n" 不會(huì)被轉(zhuǎn)義。

另外,Lua 的字符串是不可改變的值,不能像在 c 語(yǔ)言中那樣直接修改字符串的某個(gè)字符,而是根據(jù)修改要求來(lái)創(chuàng)建一個(gè)新的字符串。Lua 也不能通過(guò)下標(biāo)來(lái)訪問(wèn)字符串的某個(gè)字符。想了解更多關(guān)于字符串的操作,請(qǐng)查看String 庫(kù)章節(jié)。

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 [[]].

在 Lua 實(shí)現(xiàn)中,Lua 字符串一般都會(huì)經(jīng)歷一個(gè)“內(nèi)化”(intern)的過(guò)程,即兩個(gè)完全一樣的 Lua 字符串在 Lua 虛擬機(jī)中只會(huì)存儲(chǔ)一份。每一個(gè) Lua 字符串在創(chuàng)建時(shí)都會(huì)插入到 Lua 虛擬機(jī)內(nèi)部的一個(gè)全局的哈希表中。 這意味著

  1. 創(chuàng)建相同的 Lua 字符串并不會(huì)引入新的動(dòng)態(tài)內(nèi)存分配操作,所以相對(duì)便宜(但仍有全局哈希表查詢的開(kāi)銷),
  2. 內(nèi)容相同的 Lua 字符串不會(huì)占用多份存儲(chǔ)空間,
  3. 已經(jīng)創(chuàng)建好的 Lua 字符串之間進(jìn)行相等性比較時(shí)是 O(1) 時(shí)間度的開(kāi)銷,而不是通常見(jiàn)到的 O(n).

table (表)

Table 類型實(shí)現(xiàn)了一種抽象的“關(guān)聯(lián)數(shù)組”?!瓣P(guān)聯(lián)數(shù)組”是一種具有特殊索引方式的數(shù)組,索引通常是字符串(string)或者 number 類型,但也可以是除 nil 以外的任意類型的值。

local corp = {
    web = "www.google.com",   --索引為字符串,key = "web",
                              --            value = "www.google.com"
    telephone = "12345678",   --索引為字符串
    staff = {"Jack", "Scott", "Gary"}, --索引為字符串,值也是一個(gè)表
    100876,              --相當(dāng)于 [1] = 100876,此時(shí)索引為數(shù)字
                         --      key = 1, value = 100876
    100191,              --相當(dāng)于 [2] = 100191,此時(shí)索引為數(shù)字
    [10] = 360,          --直接把數(shù)字索引給出
    ["city"] = "Beijing" --索引為字符串
}

print(corp.web)               -->output:www.google.com
print(corp["telephone"])      -->output:12345678
print(corp[2])                -->output:100191
print(corp["city"])           -->output:"Beijing"
print(corp.staff[1])          -->output:Jack
print(corp[10])               -->output:360

在內(nèi)部實(shí)現(xiàn)上,table 通常實(shí)現(xiàn)為一個(gè)哈希表、一個(gè)數(shù)組、或者兩者的混合。具體的實(shí)現(xiàn)為何種形式,動(dòng)態(tài)依賴于具體的 table 的鍵分布特點(diǎn)。

想了解更多關(guān)于 table 的操作,請(qǐng)查看 Table 庫(kù) 章節(jié)。

function (函數(shù))

在 Lua 中,函數(shù) 也是一種數(shù)據(jù)類型,函數(shù)可以存儲(chǔ)在變量中,可以通過(guò)參數(shù)傳遞給其他函數(shù),還可以作為其他函數(shù)的返回值。

示例

local function foo()
    print("in the function")
    --dosomething()
    local x = 10
    local y = 20
    return x + y
end

local a = foo    --把函數(shù)賦給變量

print(a())

--output:
in the function
30

有名函數(shù)的定義本質(zhì)上是匿名函數(shù)對(duì)變量的賦值。為說(shuō)明這一點(diǎn),考慮

function foo()
end

等價(jià)于

foo = function ()
end

類似地,

local function foo()
end

等價(jià)于

local foo = function ()
end