zoukankan      html  css  js  c++  java
  • 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()
  • 相关阅读:
    asp.net与javascript问题
    动态加载用户控件
    ASP.NET中实现模版的动态加载
    一个简单的购物车
    给图片加上水印效果
    用存储过程自定义分页
    上传图片及显示图片
    sql server图片的保存和读取
    Legato Single Server SertupFor RMAN
    确定裸设备上控制文件的大小
  • 原文地址:https://www.cnblogs.com/jackStudy/p/4393003.html
Copyright © 2011-2022 走看看