05.18 OpenResty實戰-Lua基礎數據類型

OpenResty實戰-Lua基礎數據類型

函數 type 能夠返回一個值或一個變量所屬的類型。

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 用於表示“無效值”。一個變量在第一次賦值前的默認值是 nil,將nil 賦予給一個全局變量就等同於刪除它。

local num

print(num) -->output:nil

num = 100

print(num) -->output:100

值得一提的是,OpenResty 的 Lua 接口還提供了一種特殊的空值,即 ngx.null ,用來表示不同於 nil 的“空值”。後面在討論 OpenResty 的 Redis 庫的時候,我們還會遇到它。

boolean(布爾)

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

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") --這個沒有執行

else

print("not b") -->output:not b

end

if c then

print("c") --這個沒有執行

else

print("not c") -->output:not c

end

number(數字)

Number 類型用於表示實數,和 C/C++ 裡面的 double 類型很類似。可以使用數學函數math.floor(向下取整) 和 math.ceil(向上取整) 進行取整操作。

local order = 3.99

local score = 98.01

print(math.floor(order)) -->output:3

print(math.ceil(score)) -->output:99

一般地,Lua 的 number 類型就是用雙精度浮點數來實現的。值得一提的是,LuaJIT 支持所謂的“dual-number”(雙數) 模式,即 LuaJIT 會根據上下文用整型來存儲整數,而用雙精度浮點數來存放浮點數。

另外,LuaJIT 還支持“長長整型”的大整數(在 x86_64 體系結構上則是 64 位整數) 。例如

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

string(字符串)

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

  1. 使用一對匹配的單引號。例:'hello'。
  2. 使用一對匹配的雙引號。例:"abclua"。
  3. 字符串還可以用一種長括號(即[[ ]]) 括起來的方式定義。

我們把兩個正的方括號(即[[)間插入 n 個等號定義為第 n 級正長括號。就是說,0 級正的長括號寫作 [[ ,一級正的長括號寫作 [=[,如此等等。反的長括號也作類似定義;舉個例子,4 級反的長括號寫作 ]====]。

一個長字符串可以由任何一級的正的長括號開始,而由第一個碰到的同級反的長括號結束。整個詞法分析過程將不受分行限制,不處理任何轉義符,並且忽略掉任何不同級別的長括號。

這種方式描述的字符串可以包含任何東西,當然本級別的反長括號除外。例:[[abc\\nbc]],裡面的 "\\n" 不會被轉義。

另外,Lua 的字符串是不可改變的值,不能像在 c 語言中那樣直接修改字符串的某個字符,而是根據修改要求來創建一個新的字符串。Lua 也不能通過下標來訪問字符串的某個字符。

想了解更多關於字符串的操作,請關注後續String 庫的文章。

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 實現中,Lua 字符串一般都會經歷一個“內化”(intern) 的過程,即兩個完全一樣的Lua 字符串在 Lua 虛擬機中只會存儲一份。每一個 Lua 字符串在創建時都會插入到 Lua 虛擬機內部的一個全局的哈希表中。 這意味著

  1. 創建相同的 Lua 字符串並不會引入新的動態內存分配操作,所以相對便宜(但仍有全局哈希表查詢的開銷)
  2. 內容相同的 Lua 字符串不會佔用多份存儲空間
  3. 已經創建好的 Lua 字符串之間進行相等性比較時是 O(1) 時間度的開銷,而不是通常見到的 O(n)

table (表)

Table 類型實現了一種抽象的“關聯數組”。“關聯數組”是一種具有特殊索引方式的數組,索引通常是字符串(string) 或者 number 類型,但也可以是除 nil 以外的任意類型的值。

local corp = {

web = "www.google.com", --索引為字符串,key = "web",

-- value = "www.google.com"

telephone = "12345678", --索引為字符串

staff = {"Jack", "Scott", "Gary"}, --索引為字符串,值也是一個表

100876, --相當於 [1] = 100876,此時索引為數字

-- key = 1, value = 100876

100191, --相當於 [2] = 100191,此時索引為數字

[10] = 360, --直接把數字索引給出

["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

在內部實現上,table 通常實現為一個哈希表、一個數組、或者兩者的混合。具體的實現為何種形式,動態依賴於具體的 table 的鍵分佈特點。

想了解更多關於 table 的操作,請關注後續 Table 庫的文章。

function (函數)

在 Lua 中,函數 也是一種數據類型,函數可以存儲在變量中,可以通過參數傳遞給其他函數,還可以作為其他函數的返回值。

示例

local function foo()

print("in the function")

--dosomething()

local x = 10

local y = 20

return x + y

end

local a = foo --把函數賦給變量

print(a())

--output:

in the function

30

有名函數的定義本質上是匿名函數對變量的賦值。為說明這一點,考慮

function foo()

end

等價於

foo = function ()

end

類似地,

local function foo()

end

等價於

local foo = function ()

end

至此,Lua 基礎數據類型就介紹完了。下一篇將介紹Lua表達式。

後續計劃內容:

Lua入門+高階

Nginx

OpenResty

LuaRestyRedisLibrary

LuaCjsonLibrary

PostgresNginxModule

LuaNginxModule

LuaRestyDNSLibrary

LuaRestyLock

stream_lua_module

balancer_by_lua

OpenResty 與 SSL

測試

Web服務

火焰圖

OpenResty周邊

零碎知識點


分享到:


相關文章: