Lua學習總結二

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

運行結果如下:

Lua學習總結二

很好理解,代碼加上運行結果,一目瞭然了。

其實泛型for循環也很好理解,與C#中的foreach很相似,只是使用for循環來寫:

tab={ ley1="ant",key2="mumu" }

for k,v in pairs(tab) do
   print(k,v)
end

運行結果:

Lua學習總結二

repeat  until循環:重複循環直到滿足條件,滿足條件後就不在循環了:

a=1

repeat
    a=a+1
    print(a)
until (a>5)

一個很新穎的寫法,但是和C#中do while循環把判斷條件放在後面是一樣的。運行結果:

Lua學習總結二

循環進階那就是循環的嵌套嘍,我隨手就寫了一個冒泡排序:

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

運行結果:

Lua學習總結二

堪稱完美~~

2.流程控制

流程控制自然說的就是if else啦,與C#沒什麼太大不同。

但是要注意的是:在Lua中出了false和nil,其他的都爲true。

3.可變參數的函數

Lua中什麼是可變參數的函數呢?

我們看看例子:

print()
print(1)
print(1,2)
print(1,2,3)

Lua學習總結二

我們看到這個結果首先想到的就是面向對象中的多態。

那麼我們在Lua中怎麼去實現這樣的方法呢?

function myfun(...)      --通過...來聲明一個參數個數不定的函數
	print("我輸入了"..#arg.."個參數")      --輸入的參數會默認放在名爲arg的table中,通過#可以獲得其長度
end


myfun()
myfun(1)
myfun(1,2)
myfun(1,2,3)

我們看執行結果:

Lua學習總結二

嗯,可以說是非常有意思了。

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學習總結二

當然了我們可以爲它們賦值:

Lua學習總結二

爲什麼會出現這種情況呢

我思考的結果是: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])

輸出結果:

Lua學習總結二

試問如果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();
        }
    }

輸出結果:

Lua學習總結二

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))	--瞭解表內指定範圍的元素

輸出結果:

Lua學習總結二

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

輸出結果:

Lua學習總結二

table.remove()方法:移除表內的元素

Lua學習總結二

上面的例子中我們通過將其中一個元素置爲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

我們可以看到運行結果:

Lua學習總結二

這樣一來我們移除元素之後的表內的每一個元素都是有意義的,減少了可能會出現的錯誤。

table.sort()方法:對錶中元素進行排序

表中元素如果是number類型的,則會按照數字的大小從小到大排序,如果是字符串的話,則會按照ASCII碼錶的順序進行排序。

 

內容很多,有理解錯誤的地方歡迎大佬們批評指正,謝謝!

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