一、Lua中函数也为第一类值:函数也可以存储到变量、table中;它可以作为实参传递给其他函数,也可以作为其他函数的返回值;词法域:一个函数可以嵌套到另一个函数中,内部的函数可以访问外部函数的变量;函数与其他值一样都是匿名的,Lua中的函数只是一个持有某函数方法的变量,函数名类似于变量名,我们也可以用多种方式来操作一个函数
例:

a={p=print}
 a.p("Hello")-->与print("Hello")相同
 ----------------------------------------
 a={p=print}
 print=math.sin
 a.p(print(math.pi/2))
 结果为1
 ----------------------------------------
 a={p=print}
 sin=a.p
 sin(10,20,30)1、一个函数定义就是一条赋值语句
 例:function foo(x) return 2*x end  (1)等价于  foo=function(x) return 2*x end(2)
 (2)相当于创建了一个类型为函数的值,foo的类型为一个函数;可以将(2)等号后面的函数表达式视为函数构造式,如果只有该函数表达式的话,则称其为匿名函数
 2、table库中有一个函数sort,格式为table.sort(table参数,次序函数(匿名函数)),用于对括号内的table参数变量进行排序,可以根据次序函数中提供的两个值来决定在有序情况下第一个元素是否应该排在第二个元素之前,次序函数是可选的,可以添加也可以不添加
 例:
 network={{name="abc",IP="20.26.30.347"},
                  {name="ffrraial",IP=201.23.374.23},
                  {name="derain",IP="20.26.23.25"}}
 table.sort(network,function(a,b) return (a.name>b.name) end)(根据network中的名字来进行排序)
 3、像table.sort这样能接收其他函数返回值作为实参的函数称为高阶函数;高阶函数是一种强大的编程机制,运用匿名函数来创建高阶函数所需的实参可以带来更大的灵活性,但高阶函数本身无任何特权
 二、闭合函数:如果一个函数A写在另一个函数B中,那么这个函数A便可以访问外部函数B的局部变量,这项特征称之为词法域 
 形参也是一种局部变量
 在一个内部函数A中对另一个函数B进行修改时,内部函数A改变了函数B的用法,在内部函数A以外,函数B的用法也将被改变
 例:
 function sortbygrade(name,grades)
      table.sort(names,function(n1,n2) return grades[n1]>grades[n2] end)-->这里面的grades称为非局部的变量
 endfunction newCounter()
       local i=0
       return function()
                         i=i+1-->Lua会以闭合概念来正确的处理这种情况
                         return i-->将这个结果返回保存在将该函数作为表达式进行赋值的变量中,该变量再次被调用后,会进行将原来存储在变量中的值拿出来再次带入到newCounter函数中进行计算,忽略掉原来的local i的局部变量创建。非局部变量会直接保存在被赋值的变量中,再次使用该变量时会被进行调用,从而再次使用变量的函数
                  end
 end
 a=newCounter()
 b=newCounter()
 print(a(),b())
 print(a(),b())
 print(a(),b())
 其结果为:
 1    1
 2    2
 3    3
 --------------------------------------------
 三、函数闭包
 函数闭包:闭包(closure),通过调用含有一个内部函数加上该外部函数持有的外部局部变量(upvalue)的外部函数产生的一个实例函数
 闭包组成:外部函数+外部函数创建的upvalue+内部函数(闭包函数)
 非局部变量,即上面提到的upvalue,这个值该如何理解,如果你有C语言基础,我们不妨先将它理解为函数内部定义的“静态(static)变量”,但upvalue它有自己的特点。
 首先看upvalue的定义要求,一定是外部函数定义的的local局部变量,且在内部函数调用过。
 四、Lua中的closure(闭合函数)
 词法域:若将一个函数写在另一个函数之内,那么这个位于内部的函数便可以访问外部函数中的局部变量,这项特征称之为“词法域”。
 closure在另一种情况中也非常有用。例如在Lua中函数是存储在普通变量中的,因此可以轻易地重新定义某些函数,甚至是重新定义那些预定义的函数。这正是Lua相当灵活的原因之一。通常当重新定义一个函数的时候,需要在新的实现中调用原来的那个函数。
 例:
 do
     local oldSin = math.sin
     local k = math.pi/180
     math.sin = function (x)
         return oldSin(x*k)
     end
 end

假设要重新定义函数sin,使其参数能使用角度来替换原先的弧度。那么这个新函数就必须得转换他的实参,并调用原来的sin函数完成真正的计算。将老版本的sin保存到了一个私有变量中,现在只有通过新版本的sin才能访问它了。