lua 高级篇(一)

  第六章: 再论函数

Lua 中的函数是带有词法定界(lexical scoping)的第一类值(first-class values)。
 第一类值指:在 Lua 中函数和其他值(数值、字符串)一样,函数可以被存放在变
                  量中,也可以存放在表中,可以作为函数的参数,还可以作为函数的返回值。
词法定界指:被嵌套的函数可以访问他外部函数中的变量。这一特性给 Lua 提供了
                 强大的编程能力。

先给出一些实例,看看lua的函数是如何跟普通变量一样可以进行赋值 作为参数。。。

function foo(x) return x * 2 end

print(foo(3)) -- 6

a = {p = print}
a.p("hello world") -- hello world
print = math.sin -- print new refer to the sin function
a.p(print(1))
sin = a.p  
sin(10,20) -- 10  20  funciton print

network = {
    {name = "grauna", IP = "210.26.30.34"},
    {name = "arraial", IP = "210.26.30.23"},
    {name = "lua", IP = "210.26.23.12"},
    {name = "derain", IP = "210.26.23.20"},
    }

table.sort( network, function (a,b) return (a.name > b.name) end) --没有名字的函数 匿名函数
1 闭包

      当一个函数内部嵌套另一个函数时,内部的函数体可以访问外部的函数的局部变量,这种特征叫做词法界定。

names = {"Peter","Paul","Mary"}
grades={Mary=10,Paul=7,Mary=5}
table.sort(names,function (n1,n2) 
    return grades[n1] > grades[n2] 
end)

--实现上述功能函数

function sortBygrade(names,grades)
    table.sort(names,function (n1,n2)
        return grades[n1] > grades[n2] -- compare the grades
    end)
end

一个计数器的例子:

function newCounter()
    local i = 0
    return function ()
        i = i + 1
        return i
    end
end

c1 = newCounter()
print(c1()) --1
print(c1()) --2
c2 = newCounter()
print(c2()) --1
print(c1()) –3

技术上来讲, 闭包指值而不是指函数,函数仅仅是闭包一个原型声明;尽管如此

也可以使用闭包来实现函数重定义:

print(math.sin(100))

oldSin = math.sin
math.sin = function (x)
    return oldSin(x * math.pi / 180)
end

print(math.sin(100))

2、非全局函数

    Lua的函数可以作为全局变量也可以作为局部变量,函数使用table作用域, 有三种定义方式

-- 表和函数放在一起
Lib = {}

Lib.foo = function (x,y) 
    return x + y
end

Lib.goo = function(x,y)
    return x - y
end

-- 使用表构造函数

Lib2 = {
    foo = function(x,y) return x + y end,
    goo = function(x,y) return x - y end
}

--定义方式三


function Lib.square(x)
    return 2 * x
end

function Lib.sqrt(x)
    return math.sqrt(x)
end


print(Lib.foo(2,3))
print(Lib2.goo(4,5))
print(Lib.square(2))
print(Lib.sqrt(3))

3、正确的尾调用

   Lua函数的另外一个有趣的特征是可以正确的处理尾调用(proper tail recursion)

   尾调用是一种类似在函数结尾的goto调用,当函数最后一个动作是调用另外一个函数时,我们称这种调用为尾调用。

   例如:

function f(x)
    return g(x)
end

最后一个尾调用的例子:

  尾调用可以理解为 goto:

这个迷宫游戏是典型的状态机,每个当前的房间是一个状态。我们可以对每个房间
写一个函数实现这个迷宫游戏,我们使用尾调用从一个房间移动到另外一个房间。一个
四个房间的迷宫代码如下:

function room1()
    local move = io.read()
    if move == "south" then
        return room3()
    elseif move =="east" then
        return room2()
    else
        print("invalid move")
        return room1()
    end
 end

function room2()
     local move = io.read()
     if move == "south" then
         return room4()
     elseif move == "west" then
         return room1()
     else
         print("invalid move")
         return room2()
     end
 end

 function room3()
     local move = io.read()
     if move == "north" then
         return room1()
     elseif move =="east" then
         return room4()
     else
         print("invalid move")
         return room3()
     end
 end

 function room4()
     print("congratilations!")
 end

 room1()
原文地址:https://www.cnblogs.com/jackStudy/p/4393003.html