【系列】潛水黨的簡單lua教程二
上次講到了變量的使用規(guī)則。
這次就先講一個(gè)lua里面會(huì)頻繁使用到的東西:table(表)
table是lua的一種數(shù)據(jù)結(jié)構(gòu),可以用來儲(chǔ)存數(shù)據(jù),且table不固定大小,可以根據(jù)需要來擴(kuò)容table里的內(nèi)容。
那么如何使用table呢?請(qǐng)看耐心看完下面的內(nèi)容。
當(dāng)你想要定義一個(gè)新表的時(shí):
例:
my = {} -- 創(chuàng)建表
當(dāng)你想要讓它儲(chǔ)存數(shù)據(jù)時(shí):
例:
my[1] = ‘王大錘’
print(my[1]) -- 輸出結(jié)果:王大錘
這里是不是跟ydwe里的全局變量很相似呢?
對(duì)沒錯(cuò),但又有一定的區(qū)別。
表在存儲(chǔ)數(shù)據(jù)的時(shí)候,是會(huì)有一個(gè)索引的。
而這個(gè)索引可以是任何值,這與編輯器的全局變量的索引是截然不同的。
當(dāng)你想要移除數(shù)據(jù)時(shí):
my[1] = nil
-- 回收且釋放數(shù)據(jù)
以上是table的一些簡單操作,更進(jìn)階一點(diǎn)的用法就是,了解lua里面,專門為table提供的一些函數(shù)。
table.insert(table,[index],key):
為指定table添加key,如果存在index,那么會(huì)在索引為index的位置上添加key。
table.remove(table,[index]):
為指定table移除key,如果不存在index,則移除在table末尾的key,即index初始長度為table的長度;
如果存在index,那么會(huì)移除索引為index的key,并且排序在index其后的key全部向前移動(dòng);
insert以及remove基本上是用到最多的兩個(gè)函數(shù)。
另外還存在有sort以及concat兩個(gè)函數(shù),前者作為table的排序,后者連接table內(nèi)的值,基本用不到,這里不做多解釋。
另外還有一些常用的方法,如遍歷table內(nèi)的數(shù)據(jù),獲取table長度等等。
例:
my = {
1,?-- 數(shù)據(jù)結(jié)尾需要加上,
2, -- 否則會(huì)報(bào)錯(cuò)
3, -- 末尾數(shù)據(jù)可加可不加
}
遍歷table內(nèi)數(shù)據(jù):
for k,v in pairs (my) do?
-- 其中 k 是數(shù)據(jù)的索引, v才是數(shù)據(jù)本身
print(k, v)
end
獲取table的長度:
例1:
local num = 0
for k,v in pairs (my) do?
num = num + 1
end
print('my的長度為',num) -- 輸出結(jié)果:my的長度為3
例2:
local num = #my
print('my的長度為',num) -- 輸出結(jié)果:my的長度為3
以上就是遍歷table數(shù)據(jù)以及獲取長度的方法。
除此之外,table還可以用來做模塊、包、對(duì)象等等,不過你只做圖的話,用不到這些。
這里簡單的講一下模塊的做法,與函數(shù)有關(guān)。
新建一個(gè)lua腳本,命名為abc.lua
my = {} -- 創(chuàng)建一個(gè)新模塊
my[1]?= 123 -- 為模塊添加一個(gè)數(shù)據(jù)
-- 為模塊添加一個(gè)函數(shù)
function my.init()
print(my[1])
end
-- 返回模塊
return my
新建另一個(gè)腳本,命名為cba.lua
local my = require 'abc'
my.init() -- 調(diào)用模塊內(nèi)的函數(shù)
-- 輸出my[1]的內(nèi)容
一般來說你只是作圖的話用不到這個(gè),常規(guī)的做法是定義一個(gè)table,然后將函數(shù)、常量等等存進(jìn)table,直接調(diào)用table就可以直接使用了。
完全不需要多此一舉專門寫個(gè)模塊。
寫模塊的好處是可以被你寫的局部變量獲取到,你調(diào)用起來更自由。
table的基礎(chǔ)用法已經(jīng)講完了,接下來就是函數(shù)的定義。
jass的函數(shù)定義:
function init takes nothing returns nothing
endfunction
lua的函數(shù)定義:
function init()
end
兩者相對(duì)比較,你會(huì)發(fā)現(xiàn)lua的寫法更加簡潔。
那么lua應(yīng)該怎么為函數(shù)添加參數(shù)呢?
例:
function init(a)
print(a)
end
init(123) -- 輸出結(jié)果:123
那如果函數(shù)的參數(shù)有十幾二十多個(gè)呢?一個(gè)個(gè)寫豈不是要累死?
lua提供了一種可變參數(shù)的寫法。
例:
-- 固定參數(shù)
function init(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y ,z)
print(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y ,z)
end
-- 可變參數(shù)
function init(...)
for k, v, in ipairs {...} do
print(k, v) -- 這里的k是參數(shù)索引,v是參數(shù)值
end
end
這兩種寫法,得到的數(shù)據(jù)基本沒有區(qū)別,并且第二種可變參數(shù)的寫法,你可以根據(jù)需求去擴(kuò)展參數(shù)。
同時(shí),可變參數(shù)同樣也可以與固定參數(shù)共存,如以下寫法。
例:
function init(a, b, c, ...)
local list = {...} -- 可變參數(shù)列表
for k, v, in ipairs {...} do
print(k, v) -- 這里的k是參數(shù)索引,v是參數(shù)值
end
print(a, b, c)
end
但固定參數(shù)的位置需要在可變參數(shù)之前。
如果可變參數(shù)項(xiàng)里存在nil呢?那會(huì)不會(huì)報(bào)錯(cuò)呢?
這里可以用select('#', ...) 來獲取可變參數(shù)的長度,如果把'#'換成任意數(shù)n,那么就會(huì)從n的位置開始,獲取剩下參數(shù)項(xiàng)的長度。
接下來是函數(shù)的調(diào)用。
jass:
function init takes nothing returns nothing
endfunction
// 調(diào)用
call?init()
lua:
function init()
end
-- 調(diào)用
init()
lua不需要加上call的前綴,可以直接填寫函數(shù)名調(diào)用。
但這樣寫就是一個(gè)全局函數(shù),如果地圖長期更新,函數(shù)越來越多,會(huì)讓你很難記住每個(gè)函數(shù)的大致作用是什么。
所以就需要結(jié)合之前提到的table來使用。
往table里存函數(shù)的方法并不止一種。
my = {} -- 創(chuàng)建一個(gè)表
例1:
-- 存一個(gè)函數(shù)
function my.init()
end
例2:
-- 存一個(gè)函數(shù)
function my:init()
end
這里與例1的區(qū)別在于,例1用到的是點(diǎn),例2用到的是冒號(hào)。
兩者的區(qū)別在于,冒號(hào)會(huì)多一個(gè)self的參數(shù),self代表的是這個(gè)函數(shù)本身。
當(dāng)然例1也可以做到例2的效果,如:
function my.init(self)
end
通過這里可以看得出來,冒號(hào)的作用僅僅只是省略了一個(gè)self的參數(shù)填寫過程。
還有一種存函數(shù)的方法,如:
-- 等同于例2
my = {
init = function(self)
end
}
還有一點(diǎn)需要說明的是,lua支持局部函數(shù),與局部變量性質(zhì)一樣,只能在當(dāng)前腳本內(nèi)使用。
局部函數(shù)的寫法:
例1:
local function init()
end
例2:
local init = function()
end
其他的下次在寫,碼字碼累了。