第二課 類型和值

Lua是一種動態類型語言。沒有類型定義的語法。每個值都攜帶了它自身的類型信息。
8種基礎類型:nil(空) boolean(布爾) number(數字)
string(字符串) userdata(自定義類型) function(函數)
thread(線程) table(表)
函數type可 根據一個值返回其類型名稱。
print(type("hello world")) -->string
print(type(type)) -->function
print(type(nil)) -->nil

變量沒有預定義類型,任何變量都可以包含任何類型的值

a = print
a(type(a)) -->function
在Lua中,函數是作爲“第一類值(first-class value)”來看待的,可以像操作其他值一樣來操作函數值

nil(空)
nil是一個類型,它只有一個值nil。它的主要功能是用於區別其他任何值。

boolean(布爾)
true,false。Lua將nil和false視作“假”,其他情況均爲“真”

number(數字)
number類型用於表示實數。Lua沒有整數類型,因爲沒有必要。事實上,只要使用雙精度來表示一個整數,就不會出現“四捨五入(Rounding)”的錯誤。

string(字符串)
Lua完全採用8位編碼,Lua字符串中的字符可以具有任何數值編碼,包括數值0。
Lua中的字符串是不可變的值。所以沒有字符串變量一說。要改變字符串值只能創建一個新字符串。
字面字符串(literal string)需要以一對匹配的單引號或雙引號來界定:
a = "a line"
b = 'another line'
Lua字符串中可以有類C語言中的轉義序列。如:\n,\r等。
可以通過數值來指定字符串中的字符,數值以轉義序列“\<ddd>”給出,<ddd>是一個至多3個十進制數字組成的序列。
“alo\n123\"” == '\97lo\10\04923"'
ASCII 編碼中,'a'是97,換行是10,‘1’是49。
一對匹配的[[]]雙括號來界定一個字母字符串,就像寫塊註釋一樣。Lua不會解釋其中的轉義序列。如果字符串的第一個字符是換行字符,Lua會忽略它。
page = [[
<html>
<head>
<title>An Html Page</title>
</head>
</html>
]]
[[之中還可以加任意數量的==,兩邊許匹配==數量
[===[ ]===]
--[==[ --]==]
Lua提供了運行時的數字和字符串的自動轉換。
print("10" + 1 ) -->11
print("hello" + 1) --錯誤
同樣,在Lua期望一個字符串但卻得到一個數字時,它也會將 數字轉換成字符串。
print(10 .. 20) -->1020
..(兩個點)是字符串連接符,當直接在一個數字後面輸入它時,必須使用一個空格來分割它們。不然,Lua會將第一個點理解爲一個小數點。
比較運算符10=="10"總爲false。
如果需要顯示地將字符串轉換爲數字,可以使用函數tonumber。如果字符串的內容不能表示一個正確的數字時,tonumber將返回nil。
若要將-個數字轉換成字符串,可以調用函數tostring,或者將該數字與一個空字符串連接。
print(tostring(10) == "10") -->true
print(10 .. "" == "10") -->true
在Lua5.1中,可以在字符串前放置操作符“#”來獲得該字符串的長度。#號被稱作“長度操作符”
a = "hello"
print(#a) -->5

table(表)
table類型實現了“關聯數組”。關聯數組是一種具有特殊索引方式的數組。不僅僅可以通過整數來索引它,還可以使用字符串或者其他類型的值(除了nil)來索引它。table沒有固定的大小,可以動態地添加任意數量的元素到一個table中。Lua也是通過table來表示模塊(module)、包(package)和對象(object)的。當輸入io.read的時候,其含義是“io”模塊中的read函數。對於Lua而言,這表示“使用字符串“read”作爲key(鍵)來索引table io”
table既不是“值”也不是“變量”,而是“對象”。
table的創建是通過“構造表達式”完成的,最簡單的構造表達式是{}。
a = {} --創建一個table,並將它的引用存儲到a
k = "x"
a[k] = 10 --新條目,key="x",value=10
a[20] = "great" --新條目,key=20,value="great"
print(a["x"]) -->10
k = 20
print(a[k]) --> "great"
a["x"] = a["x"] + 1 --遞增條目"x"
print(a["x"]) -->11
table永遠是匿名的,一個持有table的變量與table自身之間沒有固定的關聯性。
a = {}
a["x"] = 10或者a.x = 10
b = a --b與a引用了同一個table
print(b["x"])或者print(b.x) -->10
b["x"] = 20
print(a["x"]) -->20
a = nil --現在只有b還在引用table
b = nil --再也沒用對table的引用了

Lua中的數組表示:
a = {}
for i = 1,10 do
a[i] = io.read()
end
就Lua的習慣而言,數組通常以1作爲索引的初始值。並且有不少機制依賴於這個慣例。
在Lua5.1中,長度操作符“#”用於返回一個數組或線性表的最後一個索引值(或爲其大小)。
--打印所有的行
for i =1,#a do
print(a[i])
end
print(a[#a]) --打印列表a的最後一個值
a[#a] = nil --刪除最後一個值
a[#a + 1] = v --將v添加到列表末尾

數組大小的概念是模糊的,因爲數組實際上是table。
對於所有未初始化的元素的索引結果都是nil。Lua將nil作爲界定數組結尾的標誌。當一個數組有空隙時,即中間存在nil時,長度操作符會認爲這些nil元素就是結尾標記,因此應該避免對那些含有空隙的數組使用長度操作符#。如果真的需要處理那些含有“空隙”的數組,可以使用函數table.maxn(Lua5.1新函數),它將返回一個table的最大正索引數。
a = {}
a[10000] = 10
print(table.maxn(a)) -->10000
i = 10;j = "10"; k = "+10"
a = {}
a[i] = "one value"
a[j] = "another value"
a[k] = "yet another value"
print(a.j) -->"another value"
print(a.k) -->"yet another value"
print(a[tonumber(j)]) -->"one value"
print(a[tonumber(k)]) -->"one value"

function(函數)
函數是作爲“第一類值”來看待的。就和其他普通類型一樣。可以存儲在變量中,可以作爲函數參數傳遞,可以作爲函數返回值返回。

userdata(自定義類型)和thread(線程)
由於userdata類型可以將任意的C語言數據存儲到Lua變量中。在Lua中,這種類型沒有太多的預定義操作,只能進行賦值和相等性測試。










































發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章