【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… 尾調用優化就是說,若是函數結束的時候調用另一個函數,那麼就能夠進行尾調用優化,就不須要保存當前函數的執行棧信息,由於這些信息後面根本用不到了。

相關文章
相關標籤/搜索