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上的新閉包。
技術上說閉包指值而不是函式,函式僅僅是閉包的一個原形宣告。