1.Lua中的循環
Lua中的循環和與C#非常類似,只是方法塊沒有{ }來包圍。
比如while循環:
a=1
while (a<=10) do
print(a)
a=a+1 --Lua中沒有a++ a--這種形式的運算哦!
end
這就是while循環的使用,至於for循環我們上一篇中展示過了數值for循環,但是Lua中還有一種叫做泛型for循環。
我們先看看數值for循環的例子:
for a=1,10,3 do --1,10,3 分別代表開始、結束、步長,步長不指定的話默認爲1
print(a)
end
運行結果如下:
很好理解,代碼加上運行結果,一目瞭然了。
其實泛型for循環也很好理解,與C#中的foreach很相似,只是使用for循環來寫:
tab={ ley1="ant",key2="mumu" }
for k,v in pairs(tab) do
print(k,v)
end
運行結果:
repeat until循環:重複循環直到滿足條件,滿足條件後就不在循環了:
a=1
repeat
a=a+1
print(a)
until (a>5)
一個很新穎的寫法,但是和C#中do while循環把判斷條件放在後面是一樣的。運行結果:
循環進階那就是循環的嵌套嘍,我隨手就寫了一個冒泡排序:
tab={ 1,3,8,5,6,9,4,2}
for a=1,8 do
for b=a+1,8 do
if tab[a]>tab[b] then
tab[a],tab[b]=tab[b],tab[a]
end
end
end
for a=1,8 do
print(tab[a])
end
運行結果:
堪稱完美~~
2.流程控制
流程控制自然說的就是if else啦,與C#沒什麼太大不同。
但是要注意的是:在Lua中出了false和nil,其他的都爲true。
3.可變參數的函數
Lua中什麼是可變參數的函數呢?
我們看看例子:
print()
print(1)
print(1,2)
print(1,2,3)
我們看到這個結果首先想到的就是面向對象中的多態。
那麼我們在Lua中怎麼去實現這樣的方法呢?
function myfun(...) --通過...來聲明一個參數個數不定的函數
print("我輸入了"..#arg.."個參數") --輸入的參數會默認放在名爲arg的table中,通過#可以獲得其長度
end
myfun()
myfun(1)
myfun(1,2)
myfun(1,2,3)
我們看執行結果:
嗯,可以說是非常有意思了。
4.運算符
算術運算符方面,與C#區別不大,只是在求餘數的操作時,Lua中是可以對小數求餘數的,比如0.9對0.2求餘數,結果爲0.1。
關係運算符方面都一樣。== > < >= <=,唯一不同的是Lua中還提供了不相等的運算符:~=
邏輯運算符方面功能是與C#一樣的,只是寫法不同了而已。and=&& or=|| not=!
比如 a and b等效於a&&b,a or b等效於a||b,not a等效於!a
5.Lua中的數組
我們可以很容易地聯想到:Lua中數組是以表來實現的,因爲我們接觸了Lua的內置數據類型,發現之後表與數組的特性最相似。
關於表的一些使用我們在前面也提到過,但是表仍然有讓人驚訝的騷操作。
比如:表的索引可以是負數,甚至表的索引可以使小數,對,沒錯就是小數:
tab={1,2,3,4}
for i=1.1,4 do
print(i,tab[i])
end
for循環的初始值是1.1,但是1.1,2.1,3.1不存在對應的值,所以爲nil。
當然了我們可以爲它們賦值:
爲什麼會出現這種情況呢
我思考的結果是:Lua中已經淡化了索引的概念,因爲表中數據就是以key-value形式存在的,連字符串都能成爲"索引",小數怎麼就不行了?所以我覺得對於Lua中的表,不能完全用C#中的數組特性來理解,而是更多地把它看做是字典。
6.Lua中的迭代器
所謂的迭代器呢我們一般在遍歷的時候會用到。比如在C#中我們會有這種形式:
int[] array=new int[];
xxxxxx
//一系列操作
xxxxxx
foreach(int num in array){
if(xxxxxx){
xxxxxxxx
}
}
而在Lua中我們之前有過例子就很類似於C#中的foreach:
tab={key1="a",key2="b",key3="c"}
for k,v in pairs(tab) do
xxxxxx
end
這裏面的pairs就是一個內置好的迭代器,簡單理解就是它可以代表tab中的每一個元素。Lua中還有一個內置迭代器ipairs。
它們的區別是:
pairs會遍歷表中所有的數據元素,但是ipairs會遍歷到第一個值爲nil的元素爲止。
比如tab[1]="a",tab[2]===nil,tab[3]="c"
遍歷的時候如果使用ipairs來輸出表中的值,只會輸出第一個,因爲第二個爲nil,往後就終止遍歷了,第三個自然也就訪問不到了。
7.Lua中的表
table是Lua中非常重要的數據類型,因此我們不得不花費較多的時間來學習它。
實際上Lua中的table是一個"引用類型",爲什麼這麼說呢?我們來看看:
tab1={1,2,3,4,5}
tab2=tab1
print(tab1[1])
print(tab2[1])
tab2[1]="a"
print(tab1[1])
print(tab2[1])
輸出結果:
試問如果tab1和tab2不是指向同一個對象,那麼修改了tab2[1]的話,爲什麼tab1[1]也會發生變化呢?沒理由呀!
那麼我們在釋放內存的時候僅僅通過tab1=nil就行了嗎?
顯然不行,tab1爲nil,可是那一塊內存區域還有tab2持有引用呢,所以當tab2也爲nil的時候,這塊內存區域纔會被垃圾回收機制釋放掉。我覺得這裏是需要注意的地方。
我們在C#編程環境下做了驗證,結果也是一樣的:
class Program
{
static void Main(string[] args)
{
int[] array = new int[3] { 1, 2, 3 };
int[] array2 = array;
Console.WriteLine(array[0]);
Console.WriteLine(array2[0]);
array2[0] = 5;
Console.WriteLine(array[0]);
Console.WriteLine(array2[0]);
Console.ReadKey();
}
}
輸出結果:
8.Lua中table提供的方法函數
table.concat方法:拼接表中元素,有三個重載。
tab1={1,2,3,4,5}
print(table.concat(tab1)) --無間隙拼接表內元素
print(table.concat(tab1,"-")) --使用指定字符來連接
print(table.concat(tab1,2,4)) --瞭解表內指定範圍的元素
輸出結果:
table.insert()方法:向表中插入元素
這個方法方便了我們向表中添加元素:
tab1={1,2,3,4,5}
table.insert(tab1,6) --直接調用方法,默認向末尾插入值
table.insert(tab1,2,1.1) --向指定位置插入值
for i=1,#tab1 do
print(tab1[i])
end
輸出結果:
table.remove()方法:移除表內的元素
上面的例子中我們通過將其中一個元素置爲nil來刪除元素,但是我們卻發現後面的元素沒有向前移動,我們在遍歷相關元素的時候有可能會出現問題的。所以我們通過Lua中table提供的方法來移除表中的元素:
tab1={1,2,3,4,5}
table.remove(tab1)
table.remove(tab1,2)
for i=1,#tab1 do
print(tab1[i])
end
我們可以看到運行結果:
這樣一來我們移除元素之後的表內的每一個元素都是有意義的,減少了可能會出現的錯誤。
table.sort()方法:對錶中元素進行排序
表中元素如果是number類型的,則會按照數字的大小從小到大排序,如果是字符串的話,則會按照ASCII碼錶的順序進行排序。
內容很多,有理解錯誤的地方歡迎大佬們批評指正,謝謝!