LUA基礎: TABLE, ARRAY, NAMESPACE, LUA的物件導向
一、table的宣告及賦值
table是Lua中的hashmap(包括其實現方式也是). 由於其包含所有陣列的功能, 所以可以認為table是擴充套件了的陣列. Lua沒有再額外提供單獨的陣列型別.
用以下的語句宣告一個空的table:
newTable = {}
可以用以下的方式向table中新增值:
newTable[2] = "14"
可以使用字串形式的key值, 但必須在字串前後新增雙引號("").
newTable["time"] = "April 14"
也可以在首次宣告table的同時進行賦值, 參考下面的語句:
newTable = {
[key1] = value1,
[key2] = value2,
...
}
陣列(array)在Lua中被當作table的一個特例, 即: 以1開始的連續整數作為key的table.
所以在宣告時不需再指定key.
newArray = {
value1,
value2,
...
}
一個table如果包含key值為1的元素, 則該元素, 以及其後以2開始的連續的整數為key值的所有元素構成的table, 稱作該table的陣列部分. 一部分table的函式只會對table的陣列部分產生作用.
和其他語言的陣列一樣, 可以通過下標獲取特定的元素, 不過下標是從1而非0開始的:
> firstTable = {"alpha", "beta", "gamma"}
> print(firstTable[1])
alpha
對比: 可以用下面的方式獲取字串形式的key所對應的值:
> print(newTable.time)
April 14
可以通過#運算子獲取陣列的長度.
> print(#firstTable)
3
#運算子不會處理table的非陣列部分.
> secondTable = {
>> "alpha",
>> "beta",
>> ["one"] = "uno",
>> ["two"] = "dos",
>> "gamma",
>> }
> print(#secondTable)
3
附註: 一個table的陣列部分可以以內建的table.sort()函式進行升序排列:
> newTable = {"alpha", "gamma", "beta"}
> table.sort(newTable)
> for i = 1, #newTable do
>> print(i, newTable[i])
>> end
1, alpha
2, beta
3, gamma
關於刪除:
在任何的table中, 都可以用下面的語句清空一個key所對應的值:
newTable["time"] = nil
以下語句只支援array形式的table:
value = table.remove(newTable)
value = table.remove(newTable, 2)
在刪除的同時將返回被刪除的key原本的值.
二、使用table建立namespace
table的一個元素的值可以是一段程式碼, 此時這個元素相當於一個函式(或方法). 換言之, 可以利用table來產生一個namespace.
回顧: 字串形式的key所對應的值, 可以通過兩種方式來獲取:
> print(newTable.time)
April 14
> print(newTable["time"])
April 14
類似的, 之前所看到的table.insert(), table.remove(), table.sort()三個函式也是table表中所儲存的資料, 換言之它們等價於
table["insert"]()
table["remove"]()
table["sort"]()
具體建立namespace並匯入函式的方式可參考下列程式碼:
> util = {}
> function convert(celsius)
>> return ((celsius * 1.8) + 32)
>> end
> util.convert = convert
> print(convert(0))
32
> print(util.convert(0))
32
或者, 更直接地:
> function util.convert(celsius)
>> return ((celsius * 1.8) + 32)
>> end
> print(util.convert(0))
32
三、通過table實現OOP
通過上述的table功能, 可以在Lua中方便地實現物件導向程式設計.
首先, 用一般的table宣告方式先宣告"private data"
counter = {
count = 0
}
接下來再追加其中的方法:
function counter.get(self)
return self.count
end
function counter.inc(self)
self.count = self.count + 1
end
這樣就構成了一個計數器物體, 有一個計數用的變數(count)以及兩個計數相關的方法, 可以這樣使用:
> print(counter.get(counter))
0
> counter.inc(counter)
> print(counter.get(counter))
1
可以再產生一個相同型別的物件, 需要重複書寫一部分程式碼; 函式可以不用重新定義.
> counter2 = {
count = 15,
get = counter.get,
inc = counter.inc,
}
> print(counter2.get(counter2))
15
這種定義方式的好處是免除了在其他OOP語言當中經常浪費程式編寫人員精力的疑問, 例如令人頭大的訪問許可權(private, public, protected之類), 以及 "我用一個=運算子copy了一個方法, 我到底是copy了方法的內容、指標, 或者只是把新方法指向了當前的方法" 等等疑問.
上述方式的一個麻煩是, 在呼叫table自身變數(例如count)的時候, 必須再將table名輸入一次(例如counter.get(counter)輸入了兩次counter). 這樣的方式, 在疏忽下可能產生混亂(如: counter2.get(counter)). 一種可行的改進方法是使用":"代替"."來呼叫object method.
在Lua中, 以下的兩種定義函式的方式是等價的:
function tbl:MyMethod() end
function tbl.MyMethod(self) end
並且, 這裡的self就是擁有此method的table. 看下面的程式碼:
counter = {
count = 0
}
function counter:get()
return self.count
end
function counter:inc()
self.count = self.count + 1
end
程式碼被進一步地優化了.
利用:的定義方式, 可以把之前的OOP語句 改造得和其他OOP語言更加接近.
do
local function get(self)
return self.count
end
local function inc(self)
self.count = self.count + 1
end
function new_counter(value) -- 注意這個function不是local的. 這是個建構器
if type(value) ~= "number" then
value = 0
end
local obj = {
count = value,
get = get,
inc = inc,
}
return obj
end
end
> counter = new_counter()
> print(counter:get())
0
> counter2 = new_counter(15)
> print(counter2:get())
15
> counter:inc()
> print(counter:get())
1
> print(counter2:get())
15
這樣的程式碼看起來和C++/Java有微妙的相似感.
相關文章
- Lua學習(二)物件導向物件
- Lua 中實現物件導向物件
- Lua學習筆記--物件導向(三)筆記物件
- 1、Lua 基礎
- lua 基礎 1
- LUA的基礎知識
- 物件導向基礎物件
- JAVA(一)JAVA基礎/物件導向基礎/高階物件導向Java物件
- JAVA物件導向基礎--物件導向介紹Java物件
- Java基礎-物件導向基礎Java物件
- JAVA物件導向基礎Java物件
- PHP物件導向基礎PHP物件
- 【Java 基礎】——物件導向Java物件
- Java基礎 --- 物件導向Java物件
- Lua Table 長度的計算
- Lua語法基礎教程(上篇)
- lua快速入門~在js基礎上,知道Lua 和 Js 的不同即可JS
- PHP 物件導向基礎概念PHP物件
- java基礎二:物件導向Java物件
- python物件導向[基礎]Python物件
- 12 物件導向基礎-1物件
- Golang 基礎之物件導向Golang物件
- 使用自定義lua解析管理器呼叫lua指令碼中的table指令碼
- lua基礎教程(轉其他網站)網站
- lua 基礎 2 型別和值型別
- 「MoreThanJava」Day 4:物件導向基礎Java物件
- 【Java基礎】物件導向開發Java物件
- 面向Python,物件導向(基礎)Python物件
- (Java筆記)物件導向基礎Java筆記物件
- PHP基礎之物件導向篇PHP物件
- Python基礎之物件導向Python物件
- 【Java基礎】--再談物件導向Java物件
- php基礎語法_物件導向PHP物件
- JAVA物件導向基礎--異常Java物件
- 0基礎lua學習(十四)封裝封裝
- 使用 Lua 進行基礎影像識別
- 物件導向(理解物件)——JavaScript基礎總結(一)物件JavaScript
- 面向Python,物件導向(基礎3)Python物件