初识Lua

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

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

  1. 数据类型  

    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。

猜你喜欢

转载自www.cnblogs.com/charsoul/p/11144932.html
LUA
今日推荐