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()

你可能感兴趣的:(lua)