函數基礎
(1)函數
格式:
function fun_name(params)
--body
end
調用方式:
o.fun(x) 或 o:fun(x)
其中冒號調用方式會隱含將o作爲函數第一個參數傳入;
參數:形參和實參數量可以不同,規則和多重賦值一致;
多重返回值:只需在return時這樣寫
return a, b, c
print可以接受不同數量的實參,多重返回值的函數可以直接作爲其它函數的參數,也可以作爲table的構造式 –> a = {f()};
(2)table.unpack
返回數組中所有值
print(table.unpack({10, 20, 30}))
local a = {10, 20, 30}
print(table.unpack(a))
local a = {}
a[1] = 10;
a[2] = 20;
a[3] = 30;
print(table.unpack(a))
(3)變長參數
lua的函數可以接受不同數量的實參
function add(...)
-- body
local s = 0
for i,v in ipairs{...} do --注意這裏是大括號
s = s + v
end
return s
end
print(add(3,4, 10, 25, 12)) --54
參數表中三個點(…)表示該函數可接受不同數量的實參。
表達式(…)的行爲類似一個具有多重返回值的函數。
把第一個和第二個參數賦給a和b :local a, b = …
可以像訪問數組一樣去訪問可變參數。
select(p1, p2):p1爲數字n,那麼select返回它第n個可變實參;p1爲‘#’select返回變長參數的總數。
function fun( ... )
-- body
local len = select('#', ...) -- 獲取長度
local params = {...}
for i=1,len do
print(params[i])
end
end
fun(3, 4, 10, 25, 12)
(4)具名實參
傳遞table
函數進階
(1)匿名函數
在lua中,函數是一種第一類值,就是和其它傳統類型一樣可以存儲到變量或table中,可以作爲實參傳遞給其它函數,還可以作爲其它函數的返回值。
函數與所有其它值一樣都是“匿名”的:函數定義有一下兩種方法,表明fun只是一個持有函數的變量,而不是函數的名稱。
unction fun( ... )
-- body
end
fun = function( ... )
-- body
print('fun')
end
使用匿名函數:
local tb = {
{name = "grauna", level = "50"},
{name = "lua", level = "10"},
{name = "arraial", level = "30"}
}
table.sort( tb,
function(a, b) --匿名函數
return (a.name < b.name)
end)
print(tb[1].name)
print(tb[2].name)
print(tb[3].name)
table.sort用於對table中元素排序
(2)閉合函數
在函數內部定義的函數,能夠通過建立一個閉合函數(closure),在外部函數已經執行完畢的情況下,還能訪問到在外部函數中的局部變量。
後來發現一個規律:所有定義在函數內部的函數,都不能直接在外部函數外部訪問,只能通過外部函數把內部函數返回出來,這樣在外部函數的外部纔可以使用,這也就是閉包函數通俗的理解吧。例如下面代碼中的 c1、c2
function fun()
-- body
local i = 1
print(i);
return function() --返回了閉包函數
-- body
i = i+1
return i
end
end
c1 = fun() --創建閉合函數 c1
c2 = fun() --創建閉合函數 c2 注意:這裏進行的操作其實是執行了fun函數,但並沒有執行匿名函數,而是把匿名函數賦值給c1、c2了,所以c1()、c2()其實執行裏面匿名函數
print(c1()) --也可以print(fun()())這樣調用,print(fun())打印是fun函數裏面的匿名函數的地址
print(c1())
print(c1())
--輸出 1 2 3 4
在fun函數中匿名函數,仍能訪問到fun作用域下的局部變量,i 對於匿名函數來講被稱作“非局部變量”。其中c1和c2是同一個函數創建的兩個不同的closure,它們各自擁有局部變量的獨立實例。
(3)非全局函數
函數可以存儲在全局變量、局部變量、table字段中。只要將函數存到一個局部變量中,該函數只能在某個特定的作用域使用。
定義:
local a = function()
-- body
end
local function a()
-- body
end
(4)尾調用消除
尾調用:當 f 調用完 g 之後就再無其他事情可做了,這種情況下,當 g 返回時,執行控制權直接返回到調用 f 的那個點上。
消除:在尾調用之後,程序不需要保存任何關於該函數的棧信息了,使得在進行尾調用時不耗費任何棧空間。
function f()
-- body
print("f")
g() -- g()是函數f的最後調用
end