簡單釋義:函數裏套函數,裏層函數可以訪問外層函數的所有局部 變量
1,lua中函數是第一類值 (他們可以存儲在變量中,做爲參數傳遞給其他函數或者做爲結果返回)
lua函數可以保存在變量中
local tbl = {}
tbl.a = print
tbl.a("輸出")
--[[
print函數賦值給 tbl表中a變量 ,那麼a變量 就指向print函數 ,擁有print函數的功能
]]
結果:
輸出
2,lua中的函數 都是沒有名字的 (匿名)
函數的構造:
function (var)
--dosomething
end
爲什麼平時看到的lua函數 都是這種形式
function name(var)
-do something
end
其實是 一種美觀的寫法 這種寫法等同於
local name = function(var)
--do something
end
實際上是 將 一個函數 賦值給了一個變量
代碼示例:
local log = function(var)
print(var)
end
log("這是一個函數賦值給了log變量")
結果:
這是一個函數賦值給了log變量
local function log(var)
print(var)
end
log("這是一個函數的美觀寫法")
結果:
這是一個函數的美觀寫法
3,高階函數(以函數作爲參數的函數)
語法:
function name(var,function)
--dosomething
end
代碼:以lua標準庫的排序函數table.sort()爲例
--------------輔助函數,用於打印表(table)-------------
local str = "" --連接字符串
local count = 2
function getTblLen(tbl)
local num = 0
for k,v in pairs(tbl) do
num = num +1
end
return num
end
function dump(tbl)
local num1 = 0
for k,v in pairs(tbl) do
if type(v) == "table" then
num = getTblLen(v)
num1 = 0
dump(v)
else
num1 = num1 + 1
if num == num1 then
str = str..k.."="..v..","
else
str = str..k.."="..v.." "
end
end
end
end
------------------------end
--按照年齡(age)升序排列表
local tblPerson = {
{name = "mayun" ,age = 18},
{name = "liqi" ,age = 43},
{name = "ruhua" ,age = 21},
}
--以下是高階函數,sort是以一個函數爲參數的函數
table.sort(tblPerson,function(a,b)
return a.age < b.age
end)
dump(tblPerson)
print(str)
--結果:name=mayun age=18,name=ruhua age=21,name=liqi age=43,
4,閉包(內層函數能訪問外層函數的所有局部變量)
代碼:
function log()
local arg = 10
--返回匿名函數(記住lua中的函數默認都是匿名的)
return function ()
arg = arg + 10 --匿名函數訪問了log函數的arg變量
return arg
end
end
local fuc = log()-- 將匿名函數賦值給fuc
print(fuc())--打印fuc的返回值
print(fuc())--打印fuc的返回值
結果:
--->20
--->30
在上述代碼中 像arg 變量在log函數中 但又能被 log中匿名函數 所訪問的 變量 稱爲 非局部變量 ,上述代碼中 調用 log函數時 ,創建arg 的log函數已經返回 但是非局部變量arg還是 可以被訪問,在lua中的閉包原理 可以 保持非局部變量不被釋放掉,保存在內存中, 從而給實現各種功能帶來了便利
”同一個閉包函數 保存在不同變量中 代表不同的閉包“ 事實上這句話的意思是 閉包得的名字不同 就是不同的閉包
local fuc1 = log()
print(fuc1())
---->20
fuc和fuc1是不同的閉包,他們建立在相同的函數值上,但是各自擁有局部變量arg的獨立實例