lua函数

作者: 亮亮同学 | 来源:发表于2019-11-15 13:04 被阅读0次

    伟人之所以伟大,是因为他与别人共处逆境时,别人失去了信心,他却下决心实现自己的目标。

    在Lua中,函数是对语句和表达式进行抽象的主要方法。既可以用来处理一些特殊的工作,也可以用来计算一些值。

    Lua 函数主要有两种用途:
    1.完成指定的任务,这种情况下函数作为调用语句使用;
    2.计算并返回值,这种情况下函数作为赋值语句的表达式使用

    Lua 编程语言函数定义格式如下:

    optional_function_scope function function_name( argument1, argument2, ...)
        function_body
        return result_params_comma_separated
    end
    

    解析:
    optional_function_scope: 该参数是可选的制定函数是全局函数还是局部函数,未设置该参数默认为全局函数,如果你需要设置函数为局部函数需要使用关键字 local。
    function_name: 指定函数名称。
    argument1, argument2, ...: 函数参数,多个参数以逗号隔开,函数也可以不带参数。
    function_body: 函数体,函数中需要执行的代码语句块。
    result_params_comma_separated: 函数返回值,

    代码:

    --加法计算
    --add 函数名 arg1,arg2参数    ,end函数块的结束符
    --a,b 要传到函数的参数
    --add(a,b) 调用函数
    
    local function add(arg1,arg2)
      print( arg1 + arg2)
    end
    local a = 1
    local b = 1
    add(a,b)      --调用add函数
    --->2
    
    --比较两个数 并打印数值最大的
    local max = 0
    local function Max(arg1,arg2)
        local result = nil
        if  arg1 > arg2 then 
            result = "the max is arg1"..arg1
        elseif  arg1 < arg2 then 
    
            result = "the max is arg2:"..arg2
        else
            result = arg1 or arg2
            result = "arg1 等于 arg2 :"..result
        end
        return result
    end
    local a,b = 12,14
    max = Max(a,b)
    
    print(max)
    
    --->the max is arg2:14
    
    

    多返回值

    Lua语言函数可以返回多个值,每个值以逗号隔开。

    local function getNum(arg1,arg2)
    
        local max = 0
        local min = 0
        if  arg1 ~= arg2 then 
            if  arg1 > arg2 then 
    
                max = arg1
                min = arg2
            else
                max = arg2
                min = arg1
            end
        else
            max = arg1 or arg2
            return max
        end
        return max,min  --两个返回值
    end
    
    local maxNum,minNum = getNum(3,2)  --两个变量对应接收赋值
    print(maxNum,minNum)
    
    --结果:3,2
    

    可变参数

    Lua 函数可以接受可变数目的参数,在函数参数列表中使用三点 ... 表示函数有可变的参数

    ...即表示 一个,两个或者多个参数

    如下代码

    --代表一个参数的情况
    local  function  getNum(...)
          --打印参数
        print(...)
    end
    getNum(1)
    
    --运行结果:1
    
    
    --代表多个参数的情况下需要做成参数数组 然后 分别打印
    local  function  getNum(...)
        --用大括号包起来 转成 参数 数组,然后用for迭代器打印参数
        local ArgArray = {...}
        for k, v in pairs(ArgArray) do
            print(v)
        end
    end
    
    getNum(1,2,3,4)
    --运行结果:1  2  3  4 
    

    注意:

    --[[
    1,所有的函数最后都有一个隐藏的return,因此不必显示书写此语句,除非需要 根据条件 中断某语句 或者返回需要的值。
    2,函数作为参数如果不写括号 则 传入的是该函数的地址;如果带括号 则先运行该函数
    3,该函数如果是作为print的参数带括号,则先运行该函数,然后打印该函数的返回值,如果没有返回值则打印空行

    ]]

    local  function func()
        print("aa")
        return 1
    end
    print(func())
    --结果:aa  1
    
    
    -------------------
    local  function func()
        print("aa")
        return 
    end
    print(func())
    --结果:aa  
    
    -------------------
    local  function func()
        print("aa")
        return 1
    end
    print(func)
    --结果:function: 0x7f9698c06430
    

    尾调用 (又称做尾调用消除)

    尾调用不会占用栈的空间 所以用起来大大节省内存
    语法格式

    function foo()
      return foo()
    end
    

    函数结尾 形如 return functionname()的 写法 叫做尾调用
    代码:

    local i = 1
    local function foo()
    i = i+1
        print("the function is foo"..i)
        return foo()
    end
    
    foo()
    

    结果:
    一直打印一段话 却不会卡死

    尾调用优化

    尾调用之所以与其他调用不同,就在于它的特殊的调用位置。函数调用会在内存形成一个"调用记录",又称"调用帧"(call frame),保存调用位置和内部变量等信息。
    如果在函数A的内部调用函数B,那么在A的调用记录上方,还会形成一个B的调用记录。等到B运行结束,将结果返回到A,B的调用记录才会消失。
    如果函数B内部还调用函数C,那就还有一个C的调用记录栈,以此类推。所有的调用记录,就形成一个"调用栈"(call stack)。
    而尾调用时,由于是函数的最后一步操作,所以不需要保留外层函数的调用记录,因为调用位置、内部变量等信息都不会再用到了,只要直接用内层函数的调用记录,取代外层函数的调用记录就可以了。

    function a() {
    let m = 1;
    let n = 2;
    return f(m + n);
    }

    //等同于
    function a() {
    return f(3);
    }

    //等同于
    f(3);

    上面代码中,如果函数f()不是尾调用,函数a()就需要保存内部变量m和n的值、f()的调用位置等信息。
    但由于调用f()之后,函数a()就结束了,所以执行到最后一步,完全可以删除a() 的调用记录,只保留f(3)的调用记录。

    这就叫做"尾调用优化"(Tail call optimization),即只保留内层函数的调用记录。
    如果所有函数都是尾调用,那么完全可以做到每次执行时,调用记录只有一项,这将大大节省内存。这就是"尾调用优化"的意义。

    相关文章

      网友评论

          本文标题:lua函数

          本文链接:https://www.haomeiwen.com/subject/qlojictx.html