一、Lua函數詳解


[寫在前面:寫這篇文章只是為了方便自己以后查閱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函數部分先寫到這里,不足的以后再補充,希望大家多提意見,謝謝!)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM