初识Lua

匿名 (未验证) 提交于 2019-12-02 23:47:01

  前几天为了用xLua,学习了Lua语言,算是能用了...吧?(其实就只是跟着过了一遍....)。但是感觉自己的记性一天不如一天(Orz),还是写个笔记好了,可能会对比着C++来。欢迎批评指正或者补充~

一.基础(几乎语言都有的东西)

    Lua的数据类型很少,只有8种: nil、boolean、number、string、userdata、function、thread、table。

    nil 和C++里的 NULL 比较像,不过要注意的是,type(nil)~=nil 因为type()函数返回的是string。

    string 可以用 " ", ' ', [[ ]] 来包裹。其中[[ ]]一般包裹一整块的字符串。

    userdata 一般存储C/C++数据。

    function 用...来表示可变长参数,并且可以返回多个值。

    thread 我也只看了协程部分,见下文。

    table 是一个有点想法的数据结构。其组成是一个数组一个hash表(我都想要.jpg)。数组的扩张方法是*2(也就是说capacity永远是2^n)。

  2.语法词法

    特殊的算术运算符和关系运算符:幂运算是 ^ ,不等于是 ~= 。

    逻辑运算符:and,or,not

    长度运算符:# ,把它放在table或者string的前面,可以返回length。.. ,可以连接不同的字符串。

    if 语法和C++差不多,多了个then而已。

1   if( 布尔表达式 1) 2   then 3      --[ 语句块 --] 4   elseif( 布尔表达式 2) 5   then 6      --[ 语句块 --] 7   else  8      --[ 语句块 --] 9   end

         循环就有讲究了,分别为while,for,repeat三种

 1   while(condition)  2   do  3      statements  4   end  5     6   for var=from,to,step do    7       statements    8   end  9   for i, v in ipairs(a) do 10      statements 11   end 12    13   repeat 14       statements 15   until( condition )

      可以看到,其实while和repeat不过是一个在前一个在后,可以归为一种。for循环第一种就是普通用一个number(必须是number)作为控制变量进行循环,第二种则是用迭代器(见下文)进行循环。但是这个for循环很有意思,他是先判定循环几次,然后只运行那么多次的statements。也就是说像

1   for i=1,10,1 do 2       i=i-2 3   end

这种并不是死循环。

二.特性(开始说一些特别的东西)

  1.迭代器

    lua里的迭代器实际上是三个变量:迭代函数不变量控制变量。像ipairs这种官方提供的函数也不过是包裹一下,返回这三个值而已。对于迭代函数来说,它需要返回两个值:控制变量新的值迭代出来的值(也就是我们实际获得的)。一旦有一次没有return,则停止迭代(待验证)。如:

  function iter(arg, index)       index = index + 1       print("index:", index)       local v = arg[index]       if(v and v~=100) then           return index,v       end   end   function foo(arg)       for i,n in iter,arg,0 do           print(n)       end   end   local a = {["h"]=50, 20, 150, 100, 1566, [20]=6}   foo(a)

    结果为

  index:    1   20   index:    2   150   index:    3

  2.元表

    由于元表这个东西不实际用,理解会很肤浅(没错就是我),大家将就着看吧......

    一个表可以有另一个表作为它的元表。我的理解是,表本身用作数据存放,元表则作为数据补充和方法实现。(所以可以把元表近似看作表本身的父表)

    表本身用作数据存放自不必说,而元表则作为数据补充体现在:若读写表本身时,表里没有其读写数据,则调用元表key为__index(读)和__newindex(写)的键值或函数。而方法实现体现在:

  运算符重载:    key   对应运算符      __add     +   __sub     -   __mul     *   __div     /   __mod     %   __unm     -   __concat  ..   __eq      ==   __lt      <   __le      <=

除了运算符重载(虽然不准确但就喜欢这么叫)外,还有__call和__tostring。前者在 Lua 调用一个值时调用,后者不多说。

  3.协程

    lua中每个协程都在一个单独的线程里。协程只有几个函数

  coroutine.create()    创建协程,返回thread对象,使用resume以重新执行协程   coroutine.resume()    重新执行协程   coroutine.yield()     挂起   coroutine.status()    查看状态(dead,suspended,running)   coroutine.wrap()     创建协程,返回function对象,调用函数为重新执行协程,其实质是非保护模式下的resume   coroutine.running()   返回线程ID

    值得注意的,一个是create和wrap的区别,见上述。一个是yield和resume的配合。如:

  co = coroutine.create(       function(a)           print(a,"a[1]=",a[1])           m = coroutine.yield(a)           print(m,"m[1]=",m[1])           m = coroutine.yield(m)           print(m,"m[1]=",m[1])           return a       end   )    co2 = coroutine.create(       function()           print("co2", coroutine.running())       end   )    f, c = coroutine.resume(co,{3,6})   print(c,"c[1]=",c[1])   s, c1 = coroutine.resume(co, {5,5})   print(c,"c[1]=",c[1])   print(c1,"c1[1]=",c1[1])   coroutine.resume(co,{6,6})   coroutine.resume(co)

    其结果为:

  table: 00559CA0    a[1]=    3   table: 00559CA0    c[1]=    3   table: 00559BD8    m[1]=    5   table: 00559CA0    c[1]=    3   table: 00559BD8    c1[1]=    5   table: 00559D68    m[1]=    6

    由此可以看出:

  1. 首次调用resume执行协程co时,参数 会赋值给协程的函数,作为函数参数   2. yeild的参数会作为resume的第二个返回值(第一个是boolean表示是否成功)   3. 再调用resume执行协程co时,参数 会赋值给协程上一次yield的返回值   4. 循环2、3直到return

    4.垃圾回收

      这就没细看了,就列个表以后忘了回来查吧。

  collectgarbage("collect"): 做一次完整的垃圾收集循环。通过参数 opt 它提供了一组不同的功能:    collectgarbage("count"):以 K 字节数为单位返回 Lua 使用的总内存数.这个值有小数部分,所以只需要乘上1024就能得到Lua使用的准确字节数(除非溢出)    collectgarbage("restart"): 重启垃圾收集器的自动运行。    collectgarbage("setpause"): 将 arg 设为收集器的 间歇率。 返回 间歇率 的前一个值。    collectgarbage("setstepmul"): 返回 步进倍率 的前一个值。    collectgarbage("step"): 单步运行垃圾收集器。 步长"大小"由arg控制。传入0时,收集器步进(不可分割的)一步。传入非0值,收集器收集相当于Lua分配这些多(K字节内存的工作。如果收集器结束一个循环将返回true 。    collectgarbage("stop"): 停止垃圾收集器的运行。 在调用重启前,收集器只会因显式的调用运行。

    5.其他(写一些杂七杂八)

: 和 . 的区别:table:function(args...)是一个语法糖, 其实质为table.function(self,args...)并自动传参self。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!