第五章 函式

2021-07-25 06:42:52 字數 3581 閱讀 9634

在lua中,函式是對語句和表示式進行抽象的主要機制。

即使呼叫函式時沒有引數,也必須要寫出一對空括號。一種特殊的例外情況:

乙個函式若只有乙個引數,且此引數是乙個字面字串或table構造式,那麼圓括號別是可有可無的。

print "hello world"

dofile 'test.lua'

print [[ a multi-line

message]] f

type {}

lua為物件導向式的呼叫也提供了一種特殊的語法---冒號操作符。表示式o.foo(o, x)的另一種寫法是o:foo(x),冒號操作符使呼叫o.foo時將o隱含地作為函式的第乙個引數。

多重返回值

lua允許函式返回多個結果,只需要在return關鍵字後列出所有的返回值即可。

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

print(s, e) -->7 9

function maximum(a)

local mi = 1 --最大值索引

local m = a[mi] --最大值

for i, val ipairs(a) do

if m < val then

m = val

mi = i

endend

return mi, m

endprint(maximum()) -->7 50

若將函式單獨作為一條語句時,lua會丟棄函式的所有返回值。

若將函式作為表示式的一部分時,lua只保留函式的第乙個返回值。

只有當乙個函式呼叫是一系列表示式中的最後乙個元素(或僅有乙個元素)時,才能獲得它的所有返回值。

一系列表示式包括4種情況:多重賦值,函式呼叫時傳入的實際引數列表,table構造式和return語句。

function foo0() end

function foo1() return "a" end

function foo2() return "a", "b" end

x, y, z = 10, foo2() --x = 10, y = a, z = b

x, y = foo2(), 20 --x = a, y = 20

x, y = foo0(), 20, 30 --x = nil, y = 20

print(foo2()) --a b

print(foo2() .. "x") --ax

t = --t =

t = --t[1] = nil, t[2] = "a", t[3] = 4

但是,可以將乙個函式呼叫放入一對圓括號中,從而迫使它只返回乙個結果。

print((foo2())) -->a

請注意return語句後面的內容是不需要圓括號的,在該位置上使用圓括號會導致不同的行為。例如return (f(x)),將只返回乙個值,而無關乎f返回了幾個值。

unpack函式----接受乙個陣列作為引數,並從下標1開始返回該陣列的所有元素

print(unpack()) -->10 20 30

a, b = unpack() --a = 10, b =20, 30被丟棄

unpack的一項重要用途體現在「泛型呼叫」機制中。

想呼叫任意函式f,而所有的引數都在陣列a中,則:

f(unpack(a))

f = string.find

a =

print(f(unpack(a))) -->3 4

變長引數

function add(...)

local s = 0

for i, v in ipairs do

s = s + v

endreturn s

endprint(add(3, 4, 5, 6)) -->18

引數列表中的3個點(...)表示該函式可接受不同數量的實參。

乙個函式如果需要訪問它的變長引數時,仍需要使用3個點(...),此時的3個點是當做表示式來使用的。表示式表示乙個由所有變長引數構成的陣列。

表示式「...」的行為類似於乙個具有多重返回值的函式,它返回的是當前函式的所有變長引數。

local a, b = ...

使用select函式訪問可能有nil值存在的變長引數列表:

呼叫select時,必須傳入乙個固定實參selector(選擇開關)和一系列變長引數。如果selector為數字n,那麼select返回它的第n個可變實參;否則,selector只能為字串「#」,這樣select會返回變長引數的總和。

for i = 1, select("#", ...) do

local arg = select(i, ...) --得到第i個引數

《迴圈體》

end注意:lua5.0中對於變長引數則有另外一套機制。lua5.0並沒有提供「..."表示式,而是通過乙個隱含的區域性table變數」table「來接受所有的變長引數。這個table還有乙個名為「n」的字段,用來記錄變長引數的 總數。

function foo(a, b, ...)

local arg = ; arg.n = select("#", ...)

《函式體》

end這套機制的缺點在於,每當程式呼叫了乙個具有變長引數的函式時,都會建立乙個新的table。而在新機制中,只有在需要時才會去建立這個用於變長引數訪問的table。

具名實參

lua中的實參傳遞機制是具有」位置性「的。但有時候通過名稱來指定實參也是很有用的。來思考乙個函式os.rename,這個函式用於檔案改名。通常會忘記第乙個引數是表示新檔案還是舊檔案。因此希望這個函式能夠接受兩個具有實際名稱的引數,例如:

--無效的演示**

rename(old = "temp.lua", new = "temp1.lua")

lua並不直接支援這種語法。但是可以通過細微的改變來獲得相同的結果。主要是將所有實參組織到乙個table中,並將這個table作為唯一的實參傳遞給函式。

rename

將rename修改為只接受乙個引數,並從這個引數中獲取實際引數:

function rename(arg)

return os.rename

end若乙個函式擁有大量引數,而其中大部分引數是可選引數的話,這種引數風格會特別有用。

例如:w = window

function window(option)

--檢查必要的引數

if type(option.title) ~= "string" then

error("no title")

elseif type(option.width) ~= "number" then

error("no width")

elseif type(option.height) ~= "number" then

error("no height")

end--其他引數都是可選的

_window(option.title,

option.x or 0,

option.y or 0,

option.width, option.height,

option.background or "white",

option.brother )

end

第五章 函式

第五章 函式 1 函式的定義 shell函式定義可以放在 bash profile 檔案中,也可以在使用該函式的指令碼中,還可以在命令列中 通過 source 或 執行bash profile檔案,使修改能夠立即生效 function 函式名 declare f 顯示定義的函式清單 export f...

python第五章 Python學習(第五章)

記錄所有的名片字典 card list defshow menu 顯示資訊 print 50 print 歡迎使用 名片管理系統 v1.0 print print 1.新增名片 print 2.顯示全部 print 3.搜尋名片 print print 0.退出系統 print 50 defnew ...

第五章 雜湊

雜湊表adt,只支援二叉樹查詢所允許的一部分操作。比如插入,刪除,查詢等。那些需要元素間排序資訊的操作將不會得到支援。比如findmin,findmax和線性時間按排序順序列印整個表的操作時不支援的。雜湊函式在理想狀態是能將任何兩個不同的關鍵字對映到不同的單元,但是這是不可能,因為關鍵字是無窮的,但...