Lua中的類型與值
Lua是一種動態類型的語言。在語言中沒有類型定義的語法,每個值都帶有其自身的類型信息。在Lua中有8中基本類型,分別是:
nil(空)類型
boolean(布爾)類型
number(數字)類型
string(字符串)類型
userdata(自定義類型)
function(函數)類型
thread(線程)類型
table(表)類型
以上是Lua中的8中基本類型,我們可以使用type函數,判斷一個值得類型,type函數返回一個對應類型的字符串描述。例如:
local iValue = 10
local fValue = 10.2
local strValue = "Hello World"
local funcValue = print
local bValue = true
local nilValue = nil
local tbValue = {}
if type(iValue) == "number" then
print("It is a number")
end
if type(fValue) == "number" then
print("It is a number")
end
if type(strValue) == "string" then
print("It is a string")
end
if type(funcValue) == "function" then
print("It is a function")
end
if type(bValue) == "boolean" then
print("It is a boolean")
end
if type(nilValue) == "nil" then
print("It is a nil")
end
if type(tbValue) == "table" then
print("It is a table")
end
nil(空)
nil是一種類型,它只有一個值nil。一個全局變量在第一次賦值前的默認值就是nil,將nil賦予一個全局變量等同於刪除它。Lua將nil用於表示一種“無效值”的情況,即沒有任何有效值得情況。
boolean(布爾)
boolean類型有兩個可選值:false和true。一定需要注意的是,在Lua中只有false和nil是“假”的,而除此之外的都是“真
number(數字)
number類型用於表示雙精度浮點數。Lua沒有整數類型,而Lua中的數字可以表示任何32位整數。
string(字符串)
Lua中的字符串通常表示“一個字符序列”。Lua完全採用8位編碼。Lua的字符串是不可變的值。不能像C語言中那樣直接修改字符串的某個字符,而是應該根據修改要求來創建一個新的字符串。Lua的字符串和其它對象都是自動內存管理機制所管理的對象,不需要擔心字符串的內存分配和釋放。在Lua中,字符串可以高效的處理長字符串。當字符串是多行存在時,可以使用“[[]]”符號來界定一個多行字符串,同時,Lua不會解釋其中的轉義序列。例如:
local page = [[
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>xxxx</title>
</head>
<body>
</body>
</html>
]]
print(page)
table(表)
table類型實現了關聯數組,關聯數組是一種具有特殊索引方式的數組;不僅可以通過整數來索引它,還可以使用字符串或其它類型的值(除了nil)來索引它。此外,table沒有固定的大小,可以動態得添加任意數量的元素到一個table中。
在Lua中,table既不是“值”,也不是“變量”,而是對象。可以將table想象成一種動態分配的對象,程序中僅僅有一個隊它們的引用(指針)。table的創建是通過“構造表達式”完成的,最簡單的構造表達式就是{}。
table永遠是匿名的,一個引用table的變量與table自身之間沒有固定的關聯性,例如以下代碼:
local a = {} -- 創建一個table,並將它的引用存儲在a
a["x"] = 10
local b = a -- b與a引用同一個table
print(b["x"])
b["x"] = 20
print(a["x"])
b = nil -- 現在只有a還在引用table
-- 錯誤:print(b["x"])
print(a["x"])
a = nil -- 現在不存在對table的引用
當對一個table的引用爲0時,Lua的垃圾收集器最終會刪除該table,並釋放它所佔用的內存空間。當table的某個元素沒有初始化時,它的內容就是nil;另外還可以像全局變量一樣,將nil賦予table的某個元素來刪除該元素。
在Lua中,對於a[“name”]這種形式的寫法提供了一種更簡便的寫法,可以直接輸入a.name。先看看以下代碼:
local a = {}
a["name"] = 10
print(a.name) -- 等價於print(a["name"])
這種寫法本身提供了簡便性,但是有的時候,卻給程序員帶來了困惑;我就常常會把a.x和a[x]搞錯,a.x表示a[“x”],表示以字符串”x”來索引table;而a[x]是以變量x的值來索引table。通過下面這段代碼,來看看它們之間的區別:
local a = {}
x= "y"
a[x] = 10
print(a[x]) -->10 相當於a["y"]
print(a.x) -->nil 相當於a["x"]
print(a.y) -->10 相當於a["y"]
在Lua 5.1中,長度操作符“#”用於返回一個數組或線性表的最後一個索引值。在實際項目中,我們經常使用該操作符來獲取數組或線性表的長度。但是使用該操作符是存在陷阱的,比如下面一段代碼
local a = {}
a[1000] = 1
print(#a)
這該輸出多少呢?
在Lua中,對於所有未初始化的元素的索引結果都是nil。Lua將nil作爲界定數組結尾的標誌。當一個數組有“空隙”時,即中間含有nil時,長度操作符會認爲這些nil元素就是結尾標記。因爲a[1] = nil,所以,對於上述代碼的輸出應該是0。所以,在處理table的時候,需要考慮這個問題。那麼對於含有nil的table,如何獲取它的長度呢?我們可以使用table.maxn,它將返回一個table的最大正索引數,如下所示:
local a = {}
a[1000] = 1
print(table.maxn(a)) -->1000
function(函數)
在Lua中,函數被當做值來對待,這表示函數可以存儲在變量中,可以通過參數傳遞給其它函數,還可以作爲其它函數的返回值。Lua既可以調用自身Lua語言編寫的函數,又可以調用以C語言編寫的函數。Lua所有的標準庫都是用C語言寫的。
userdata(自定義類型)和thread(線程)
userdata用於表示一種由應用程序或C語言庫所創建的新類型。由於userdata類型可以將任意的C語言數據存儲到Lua變量中。在Lua中,這種類型沒有太多的預定義操作,只能進行賦值和相等性測試。
thread主要用於“協同程序”