lua语言萌新之路

lua编程

lua函数和闭包理解

  • lua函数

    • lua函数实现是使用一个匿名函数去赋值给一个变量,例如

      local f
      f=function(x,y) do
      print (x,y)
      end
      f(1,2)
      
  • 闭包

    • 当编写一个被其他函数B包含的函数A时,被包含的函数A可以访问包含其的函数B的所有局部函数,例如

      function newCounter()
      local count=1
      return function()
      count=count+1
      return count
      end
      end
      
      c1=newCounter()
      print(c1())   1
      print(c1())     2
      
  • 函数

    • 函数只有一个参数且该参数是字符串变量或表构造器时,括号是可选的

      type{}
      
    • 调用参数时使用的参数个数可以与定义函数时使用的参数个数不一致,lua语言通过抛弃多余参数和将不足的参数设为nil的方式来调整参数的个数。

      function f(a,b) print(a,b) end
      f()
      f(3)
      
    • 当我们调用f(g())时,如果f的参数是固定的,那么lua语言会把g返回值的个数调整成与f的参数个数一致

    • 将函数调用用一对圆括号括起来可以强制其只返回一个结果

      print((foo2()))
      function foo2() return "a","b" end
      
    • 可变长参数函数

      • 参数列表中的三个点(...)表示该函数的参数是可变长的。

      • 当这个函数被调用时,lua内部会把它的所有参数收集起来,我们把这些被收集起来的参数称为函数的额外参数。

        function foo (...)
        local a,b,c = ...
        
        -- 第二种
        function id (...) return ... end
        
    • table.pack解决表中判断原始参数中是否有nil

      function nonils (...)
      local arg=table.pack(...)
      for i=1,arg.n do
       if arg[i]==nil then return false end
       end
       return true
      end
      
    • 比较table.pack和select函数

      • 对于参数较少的情况,select函数更快,因为少创建了一个中间表。
      • 参数较多table.pack函数更快(空间换时间)
    • 局部递归函数

      local fact 
      fact=function(n)
      if n==0 then return 1
      else return n*fact(n-1)
      end
      end
      
  • lua数据结构

    • lua语言中一般以1作为数组的起始索引
    • lua字符串是不可变值
  • lua编译

    • lua是解释型语言,解释型语言并不在于源码是否被编译,而在于是否有能力执行动态生成的代码
    • dofile与loadfile的区别
      • dofile执行失败,抛出异常
      • loadfile执行失败,只返回错误码
    • lua使用pcall捕获执行中发生的所有错误
  • 函数require

    • require函数首先在表package.loaded中检查模块是否已经被加载。
    • 如果模块尚未加载,那么函数require则搜索只有指定模块名的lua文件(搜索路径由变量package.path指定)
  • 迭代器

    • 迭代器是一种可以让我们遍历一个集合中所有的元素的代码结构,迭代器需要在连续的调用之间保存一些状态,这样才能知道当前迭代所处的位置以及如何从当前位置步进到下一位置

    • 简单迭代器实现

      function iters(t)
      local i=0
      return function() i=i+1;return t[i] end
      end
      
    • 泛型for,为一次迭代循环做了所有的记录工作,在内部保存了迭代函数,因此不需要变量iter,每次做新的迭代时都会再次调用迭代器,并在迭代器返回nil时结束循环,泛型for在循环过程中在其内部保存了迭代函数,实际上,泛型for保存了三个值:一个迭代函数、一个不可变状态和一个控制变量

  • table检查数据变了

    db={openid="openid_123",token="token_123"}
    cache={}
    
    setmetatable(cache,{
    __index=function(t,k)
    return db[k]
    end,
    __newindex=function(t,k,v)
    if k~="__dirty" then
     db.__dirty = true
     end
     db[k]=v
     end,
     __pairs=function(t,k)
     return next,db,k
     end,
    })
    
    for k,v in pairs(cache) do
    print(k,v)
    end
    
    cache.__dirty=nil
    print("cache.__dirty",cache.__dirty)
    
    cache.token="token_456"
    print("cache.__dirty",cache.__dirty)
    
    --[[ 
    输出结果
    openid	openid_123
    token	token_123
    cache.__dirty	nil
    cache.__dirty	true
    ]]
    
posted @ 2021-12-26 16:47  liter_wave  阅读(29)  评论(0编辑  收藏  举报