[寫在前面:寫這篇文章只是為了方便自己以后查閱Lua的基礎知識,並無深刻見解,完全參考《Lua程序設計(第二版)》]
一、函數基礎
1.函數定義
(1)標准形式:f = function(<參數>) <函數體> end
(2)語法糖形式:function f(<參數>) <函數體> end
2.函數調用
(1)一般形式:函數名(<參數>),圓括號一般是必須的
(2)省略圓括號()的情況:函數只有一個參數,並且此參數為字面字符串(“”)(注:不是字符串變量)或table構造式({})
例如:print"Hello Lua"等價於print("Hello Lua"),f{x=10,y=20} 等價於f({x=10,y=20})
(3)實參數量:當實參數量與形參數量不一致時,采用“多余舍棄,不足則形參為nil”原則
3.多重返回值
(1)含義:一個函數返回多個結果(值),即在return r1,r2,r3...
(2)返回值情況
①不返回值:函數調用作為單獨一條語句。例如:f()
②返回第一個值:函數調用作為表達式的一部分(與③對立),或將函數放入一對圓括號中(例如:(f()))。
③返回所有值(或盡可能多的值):函數調用是 一系列表達式 中的最后一個元素(或僅有一個元素),只要不是最后一個元素就最多返回一個值。
“一系列表達式”的4種形式:1.多重賦值,2.函數調用時傳入的實參列表,3.table的構造式,4.return語句
(3)注意:return 語句后面的類容不需要圓括號,否則會出現不同行為而得不到想要的結果,return(f(x))也不會得到f(x)的返回值。
4.變長參數
(1)函數形式:f(<固定參數列表>,...),三個點(...)表示函數可接受不同數量的實參,固定參數列表一定要在變長參數前面。
(2)訪問方式:當訪問變長參數(...)時,仍要用到三個點(...),此時作為表達式來使用,表達式“...”的行為類似一個具有多重返回值的函數。
例如:多重賦值:local a,b,c = ...,table構造式:{...}作為table使用,遍歷table即可訪問參數
(3)select函數:①select("#",...):返回變長參數的總數,包括中間nil的個數,②select(n,...):返回第n個實參的值
5.具名實參
含義:指定參數的名稱。即函數接受一個table作為參數,函數會調用table中指定的字段
6.常用函數
(1)unpack(array):接受一個數組作為參數,從下標1開始返回數組中的元素,包括中間為nil的元素。
二、深入函數
1.深層含義
(1)函數是“第一類值”:函數和其他傳統類型的值具有相同的權利。例如:存儲到變量或table,即賦值,作為實參傳遞給函數,作為其他函數的返回值。
(2)函數具有特定的“詞法域”:一個函數可以嵌套在另一個函數中,內部函數可以訪問(並保存,即closure)外部函數的變量。
(3)函數是“匿名的”:函數可以沒有名稱,一般情況下,討論函數時實際上是討論一個持有某函數的變量,函數變量和其他變量一樣,可以有多種方式操作它。
(4)函數定義是一條語句:這條語句創建了一種類型為“函數”的值,並賦給一個變量。
2.閉合函數(closure)
(1)定義:closure = 函數f + 函數f所需訪問的所有“非局部的變量”(即外部函數的變量)。如果沒有變量,則closure = 函數f,即函數是一個特殊的closure。
(2)形式:function F(x) ... return function ...end end
(3)作用:可保存外部函數的變量的狀態,是外部函數中的局部變量具有“全局變量”的功能
【閉合函數很強大,暫時不知道怎么去描述,以后再補充】
3.非全局的函數
(1)解釋:(還沒弄明白這個名字是怎么來的)
(2)Lua展開局部函數的“語法糖”形式定義:
local function f(<參數>) <函數體> end Lua將其展開為:
①local f
②f = function(<參數>) <函數體> end
(3)直接遞歸函數定義:不能使用“語法糖”形式,而要使用展開后的形式
(4)間接遞歸函數定義:要先向前聲明函數(定義時別再用local修飾,不然相當於重新定義了一個新函數)
4.正確的尾調用
(1)尾調用的含義:當一個函數調用是另一個函數的最后一個動作時,該調用才算是一條“尾調用”。
(2)尾調用的形式:return <func>(<args>)。lua會在調用前對func及參數args求值,即他們可以是任意復雜的表達式
(3)判斷標准:一個函數在調用完另一個函數之后是否就沒有其他事情需要做了
(4)尾調用的優點:不會耗費棧空間。(尾調用之后程序不需要保存任何關於當前函數的棧信息了)
(5)尾調用的應用:直接和間接遞歸
(Lua函數部分先寫到這里,不足的以后再補充,希望大家多提意見,謝謝!)