函數(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 是一種類型,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ì)遇到它。
布爾類型,可選值 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í)數(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
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è)全局的哈希表中。 這意味著
O(1)
時(shí)間度的開(kāi)銷,而不是通常見(jiàn)到的 O(n)
.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é)。
在 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