Lua学习总结二

1.Lua中的循环

Lua中的循环和与C#非常类似,只是方法块没有{ }来包围。

比如while循环:

a=1
while (a<=10) do
    print(a)
    a=a+1      --Lua中没有a++ a--这种形式的运算哦!
end

Lua学习总结二_第1张图片

这就是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码表的顺序进行排序。

 

内容很多,有理解错误的地方欢迎大佬们批评指正,谢谢!

你可能感兴趣的:(Lua)