Lua語言入門(二)

函數(shù)

24、函數(shù)
格式:

function fun_name(params)
--body
end

調用方式:o.fun(x)o:fun(x),其中冒號調用方式會隱含將o作為函數(shù)第一個參數(shù)傳入;

參數(shù):形參和實參數(shù)量可以不同,規(guī)則和多重賦值一致;

多重返回值:只需在return時這樣寫 -- return a, b, c
print可以接受不同數(shù)量的實參,多重返回值的函數(shù)可以直接作為其它函數(shù)的參數(shù),也可以作為table的構造式 --> a = {f()};

25、table.unpack:返回數(shù)組中所有值

print(table.unpack({10, 20, 30}))
local a = {10, 20, 30}
print(table.unpack(a))
local a = {}
a[1] = 10;
a[2] = 20;
a[3] = 30;
print(table.unpack(a))

26、變長參數(shù):lua的函數(shù)可以接受不同數(shù)量的實參

function add(...)
 -- body
 local s = 0
 for i,v in ipairs{...} do  --注意這里是大括號
  s = s + v
 end
 return s
end

print(add(3,4, 10, 25, 12))    --54

參數(shù)表中三個點(...)表示該函數(shù)可接受不同數(shù)量的實參。
表達式(...)的行為類似一個具有多重返回值的函數(shù)。
把第一個和第二個參數(shù)賦給a和b :local a, b = ...
可以像訪問數(shù)組一樣去訪問可變參數(shù)。
select(p1, p2):p1為數(shù)字n,那么select返回它第n個可變實參;p1為‘#’select返回變長參數(shù)的總數(shù)。

function fun( ... )
 -- body
 local len = select('#', ...) -- 獲取長度
 local params = {...}
 for i=1,len do
  print(params[i])
 end
end

fun(3, 4, 10, 25, 12)

27、具名實參:傳遞table

28、深入理解函數(shù)
在lua中,函數(shù)是一種第一類值,就是和其它傳統(tǒng)類型一樣可以存儲到變量或table中,可以作為實參傳遞給其它函數(shù),還可以作為其它函數(shù)的返回值。
函數(shù)與所有其它值一樣都是“匿名”的:函數(shù)定義有一下兩種方法,表明fun只是一個持有函數(shù)的變量,而不是函數(shù)的名稱。

function fun( ... )
 -- body
end

fun = function( ... )
 -- body
 print('fun')
end

使用匿名函數(shù):

local tb = {
 {name = "grauna", level = "50"},
 {name = "lua", level = "10"},
 {name = "arraial", level = "30"}
}

table.sort( tb,
 function(a, b)  --匿名函數(shù)
  return (a.name < b.name)
 end)

print(tb[1].name)
print(tb[2].name)
print(tb[3].name)

table.sort用于對table中元素排序


深入理解函數(shù)

29、閉合函數(shù):在函數(shù)內部定義的函數(shù),能夠通過建立一個閉合函數(shù)(closure),在外部函數(shù)已經執(zhí)行完畢的情況下,還能訪問到在外部函數(shù)中的局部變量。

后來發(fā)現(xiàn)一個規(guī)律:所有定義在函數(shù)內部的函數(shù),都不能直接在外部函數(shù)外部訪問,只能通過外部函數(shù)把內部函數(shù)返回出來,這樣在外部函數(shù)的外部才可以使用,這也就是閉包函數(shù)通俗的理解吧。例如下面代碼中的 c1、c2

function fun()
 -- body
 local i = 1
 print(i);
 return function()   --返回了閉包函數(shù)
  -- body
  i = i+1
  return i
 end
end

c1 = fun() --創(chuàng)建閉合函數(shù) c1
c2 = fun() --創(chuàng)建閉合函數(shù) c2                  注意:這里進行的操作其實是執(zhí)行了fun函數(shù),但并沒有執(zhí)行匿名函數(shù),而是把匿名函數(shù)賦值給c1、c2了,所以c1()、c2()其實執(zhí)行里面匿名函數(shù)

print(c1()) --也可以print(fun()())這樣調用,print(fun())打印是fun函數(shù)里面的匿名函數(shù)的地址
print(c1())
print(c1())

--輸出 1 2 3 4

在fun函數(shù)中匿名函數(shù),仍能訪問到fun作用域下的局部變量,i 對于匿名函數(shù)來講被稱作“非局部變量”。其中c1和c2是同一個函數(shù)創(chuàng)建的兩個不同的closure,它們各自擁有局部變量的獨立實例。

30、非全局函數(shù):函數(shù)可以存儲在全局變量、局部變量、table字段中。只要將函數(shù)存到一個局部變量中,該函數(shù)只能在某個特定的作用域使用。
定義:

local a = function()
 -- body
end
local function a()
 -- body
end

31、尾調用消除
尾調用:當 f 調用完 g 之后就再無其他事情可做了,這種情況下,當 g 返回時,執(zhí)行控制權直接返回到調用 f 的那個點上。
消除:在尾調用之后,程序不需要保存任何關于該函數(shù)的棧信息了,使得在進行尾調用時不耗費任何棧空間。

function f()
 -- body
 print("f")

 g()  -- g()是函數(shù)f的最后調用
end

編譯、執(zhí)行、錯誤

32、編譯:區(qū)分解釋型語言的主要特征不是能否去編譯它們,而是在編譯器是否是運行時庫的一部分,是否有能力執(zhí)行動態(tài)生成的代碼。

dofile:實際是調用loadfile,從文件加載lua代碼,編譯并運行,會引發(fā)錯誤

loadfile:從文件加載lua代碼,編譯但不運行(編譯成函數(shù),作為匿名函數(shù)返回),不會引發(fā)錯誤,有錯誤時只是返回錯誤值
源代碼 foo.lua

function foo(x)
 -- body
 print(x)
end

運行:

f = loadfile("foo.lua") --只是返回了函數(shù),但沒有執(zhí)行
print(foo)    --nil
f()               --定義foo函數(shù)
foo("ok")    --ok

load(低版本中是loadstring):從一個字符串讀取代碼,返回一個函數(shù)。(比直接定義函數(shù)寫代碼慢得多)

i = 32
local i = 0
f = load("i = i+1;print(i)") --load總是在全局環(huán)境中編譯的,所以這里訪問到的i是全局變量i
g = function() i = i+1;print(i) end

f()
g()

--輸出 33  1

33、C代碼:需要使用前先鏈接入應用程序
loadlib函數(shù)加載指定的庫,并將其鏈接入Lua:將C函數(shù)作為Lua函數(shù)返回

local path = "/usr/local/lib/lua/5.1/socket.so"
local f = package.loadlib(path, "luaopen_socket")

34、錯誤(error):只要發(fā)生錯誤,Lua就會結束當前程序塊并返回應用程序
error

if not n then
error("invalid input") --顯示拋出錯誤信息
end

assert(p1, p2):如果p1為true,就簡單返回該參數(shù),否者引發(fā)一個錯誤。p2是錯誤信息,可選

35、錯誤處理和異常:pcall(protected call)來包裝需要執(zhí)行的代碼,捕獲函數(shù)執(zhí)行中任何錯誤。

function fun( ... )
 -- body
 print("fun")
 error("exception")
end

local status, err = pcall(fun)
if status then
 --運行fun時沒有發(fā)生錯誤
 print("not have error")
else
 --錯誤處理代碼
 print("have error")
 print(err) --只要錯誤消息是字符串,Lua就會附加一些錯誤發(fā)生位置的信息
end
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容