1. 程式人生 > >lua學習筆記之函式

lua學習筆記之函式

Lua學習筆記之函式

1、  函式的作用

函式主要完成指定的任務,這樣的情況下函式作為呼叫語句使用,函式可以計算並返回值,這樣的情況下函式作為賦值語句的表示式使用。

語法:

funcationfunc_name(arguments-list)

Statements-list

end

呼叫函式的時候,如果引數列表為空,必須使用()表示是函式呼叫。

Print(8*9,9/8)

a = math.sin(3) +math.cos(10)

print(os.date())

上述規則有一個例外,當函式只有一個引數並且這個引數是字串或者表構造的時候,()是可選的:

print “hello world”    <--> print(“hello world”)

dofile ‘a.lua’    <-->dofile(‘a.lua’)

lua函式實參和形參的匹配與賦值語句類似,多餘部分被忽略,缺少部分用nil補足.

2、  返回多個結果值

Lua函式可以返回多個結果值,比如strng.find,其返回匹配串“開始和結束的下標”(如果不存在匹配串返回nil)

s,e = string.find(“hello lua users”,”lua”)

print(s,e)   -->7 9

lua函式中,在return後列出要返回的值得到列表即可返回多值,如:

function maximum(a)

local mi = 1

local m = a[mi]

for i,val inipairs(a) do

ifval >m then

mi = i

m = val

     end

     return m,mi

end

print(maxmun({8,10,23,12,5}))  -->23 3

3、  可變引數

Lua函式可以接受可變數目的引數,和C語言類似在函式引數列表中使用三點(…)表示函式有可變的引數。Lua將函式的引數放在一個叫arg的表中,除了引數以外,arg表還有一個域n表示引數的個數。

4、  命名引數

Lua的函式引數是和位置相關的,呼叫時實參會按照順序依次傳遞給形參。有時候用名字指定引數是很有用的,比如rename函式用來給一個檔案重新命名,有時候我們記不起命名前後兩個引數的順序:

rename(old = “temp.lua”,new = “temp1.lua”)

上面的程式碼是無效,lua可以通過將所有的引數放在一個表中,把表作為函式的唯一引數來實現上面這段虛擬碼的功能,因為lua語法支援函式呼叫時實參可以是表的構造。

Rename{old = “temp.lua”,new = “temp1.lua”}

根據這個想法我們重定義了rename:

functionrename(arg)

returnos.rename(arg.old,arg.new)

end

5、  閉包

當一個函式內部巢狀另一個函式定義時,內部的函式體可以訪問外部的函式的區域性變數,這個特種我們稱為詞法定界。雖然這個看起來很清楚,事實並非如此:

假如有一個學生姓名的列表和學生名和成績對用的表:現在根據學習生的成績從高到低對學生進行排序,可以這樣做:

Names = {“peter”,”paul”,”mary”}

Grades = {mary =10,paul = 7,peter = 8}

Table.sort(Names,function(n1,n2))

ReturnGrades[n1]>Grades[n2]

end)

建立一個函式實現此功能
function sortbygrade (Names,Grades)

table.sort(Names,function(n1,n2))

returnGrades[n1]>Grades[n2]

end)

end

例子中包含在sortbygrade函式內部的sort中的匿名函式可以訪問sortbygrade的引數Grades,在匿名函式內部Grades不是全域性變數也不是區域性變數,我們稱為外部的區域性變數。

看如下程式碼:

functionnewCounter()

locali = 0

returnfunction()    --匿名函式

      i = i+1        --外部的區域性變數

return i

   end

end

c1 = newCounter()

print(c1())   --> 1

print(c1())   --> 2

匿名函式使用外部的區域性變數儲存它的計數,當我們呼叫匿名函式的時候i已經超出了作用範圍,因為建立i的函式newCounter已經返回了,然後Lua用閉包的思想正確的處理了這樣的情況。簡單說閉包是一個函式加上它可以正確訪問外部的區域性變數。如果我們再次呼叫newCounter,將建立一個新的區域性變數i,因此我們得到一個作用在新的變數i上的新閉包。

技術上說閉包指值而不是函式,函式僅僅是閉包的一個原形宣告。