【Lua学习笔记6】Lua中的函数

函数声明

function hello() 
    print('hello Lua')
end
hello()
复制代码

注意,lua中的函数,不能用{}包起来,否则会报错的。html

返回多个值

function test() 
    return 1, 2
end
test()
复制代码

可变参数

function log(...) 
    -- 这里必需要这样赋值下,不过看官方文档里面好像没有这句,我本身跑没有这句报错
    local arg = {...}
    print('参数长度:' .. select('#', ...)) --> 参数长度:4
    print('第一个参数:' .. select(1, ...)) --> 第一个参数:1
    for k,v in ipairs(arg) do
        print(k .. v)
    end
end
log(1,2,3,4)
复制代码

这里使用了lua中内置的一个函数select,select('#', ...) 表示获取参数的个数, select(n, ...) 表示获取可变参数中的第n个参数的值。闭包

闭包

对,没错,就是js里面你理解的那个闭包,举个例子就行。函数

function createCounter() 
    i = 1; 
    return function() 
                i = i + 1
                return i
           end
end
counter = createCounter()
print(counter())   --> 2
print(counter())   --> 3
print(i) --> 3
复制代码

注意上面的i是全局变量,若是你只想i在函数内部访问,使用local关键字来声明一个局部变量。优化

非全局函数

上面咱们定义的其实都是全局函数,那怎么定义非全局函数呢?想一想以前说过的table,咱们能够在一个table对象上定义函数属性,这样来实现咱们的效果。ui

方式一:lua

Lib = {
    fun1 = function() return 1 end,
    fun2 = function() return 2 end
}
print(Lib.fun1())  --> 1
print(Lib.fun2())  --> 2
复制代码

方式二:spa

Lib = {
}
Lib.fun1 = function() return 1 end
Lib.fun2 = function() return 2 end
print(Lib.fun1())  --> 1
print(Lib.fun2())  --> 2
复制代码

这个是否是跟js里面的对象很类似?code

除了上面这种写法以外,Lua中还支持另一种特殊的方式:htm

方式三:对象

Lib = {
}
function Lib.fun1() return 1 end
function Lib.fun2() return 2 end
print(Lib.fun1())  --> 1
print(Lib.fun2())  --> 2
复制代码

咱们也能够将函数存储到一个局部变量中,这样这个函数的做用范围就是跟这个局部变量同样的范围了。

do
local fun1 = function()
    return 1
    end
print(fun1())  --> 1
end
复制代码

这里定义的fun1,只能在当前的do end块中能够访问到,外部没法访问。

定义局部函数lua中还支持另一种方式:

do
local function fun1()
    return 1
    end
print(fun1())  --> 1
end
复制代码

这两种方式通常状况下是等价的,除了递归。

来看个例子:

local fact = function (n)
    if n == 0 then return 1
    else return n*fact(n-1)   -- 会报错
    end
end
复制代码

官方文档里面的说法是,在编译函数的时候,会发现fact此时尚未声明,而后报错。

下面这种方式就没有问题。

local function fact (n)
    if n == 0 then return 1
    else return n*fact(n-1)
    end
end
复制代码

固然,若是你非要像上面那样写,怎么办呢?也是能够的:

local fact
fact = function (n)
    if n == 0 then return 1
    else return n*fact(n-1)   -- 会报错
    end
end
复制代码

就会先声明该函数变量,这个时候编译的时候就不会报错了,运行时函数变量已经赋值过了,因此不会有问题。

尾调用优化

function g() return 1;
function f() {
    return g()
}
复制代码

lua里面也有尾调用优化,若是不知道什么是尾调用优化,建议参考阮一峰老师的这篇文章 www.ruanyifeng.com/blog/2015/0… 尾调用优化就是说,若是函数结束的时候调用另一个函数,那么就能够进行尾调用优化,就不须要保存当前函数的执行栈信息,由于这些信息后面根本用不到了。

相关文章
相关标签/搜索