Lua语言入门(二)

函数

24、函数
格式:

function fun_name(params)
--body
end

调用方式:o.fun(x)o:fun(x),其中冒号调用方式会隐含将o作为函数第一个参数传入;

参数:形参和实参数量可以不同,规则和多重赋值一致;

多重返回值:只需在return时这样写 -- return a, b, c
print可以接受不同数量的实参,多重返回值的函数可以直接作为其它函数的参数,也可以作为table的构造式 --> a = {f()};

25、table.unpack:返回数组中所有值

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、变长参数:lua的函数可以接受不同数量的实参

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

参数表中三个点(...)表示该函数可接受不同数量的实参。
表达式(...)的行为类似一个具有多重返回值的函数。
把第一个和第二个参数赋给a和b :local a, b = ...
可以像访问数组一样去访问可变参数。
select(p1, p2):p1为数字n,那么select返回它第n个可变实参;p1为‘#’select返回变长参数的总数。

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、深入理解函数
在lua中,函数是一种第一类值,就是和其它传统类型一样可以存储到变量或table中,可以作为实参传递给其它函数,还可以作为其它函数的返回值。
函数与所有其它值一样都是“匿名”的:函数定义有一下两种方法,表明fun只是一个持有函数的变量,而不是函数的名称。

function fun( ... )
 -- body
end

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

使用匿名函数:

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

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

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

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


深入理解函数

29、闭合函数:在函数内部定义的函数,能够通过建立一个闭合函数(closure),在外部函数已经执行完毕的情况下,还能访问到在外部函数中的局部变量。

后来发现一个规律:所有定义在函数内部的函数,都不能直接在外部函数外部访问,只能通过外部函数把内部函数返回出来,这样在外部函数的外部才可以使用,这也就是闭包函数通俗的理解吧。例如下面代码中的 c1、c2

function fun()
 -- body
 local i = 1
 print(i);
 return function()   --返回了闭包函数
  -- body
  i = i+1
  return i
 end
end

c1 = fun() --创建闭合函数 c1
c2 = fun() --创建闭合函数 c2                  注意:这里进行的操作其实是执行了fun函数,但并没有执行匿名函数,而是把匿名函数赋值给c1、c2了,所以c1()、c2()其实执行里面匿名函数

print(c1()) --也可以print(fun()())这样调用,print(fun())打印是fun函数里面的匿名函数的地址
print(c1())
print(c1())

--输出 1 2 3 4

在fun函数中匿名函数,仍能访问到fun作用域下的局部变量,i 对于匿名函数来讲被称作“非局部变量”。其中c1和c2是同一个函数创建的两个不同的closure,它们各自拥有局部变量的独立实例。

30、非全局函数:函数可以存储在全局变量、局部变量、table字段中。只要将函数存到一个局部变量中,该函数只能在某个特定的作用域使用。
定义:

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

31、尾调用消除
尾调用:当 f 调用完 g 之后就再无其他事情可做了,这种情况下,当 g 返回时,执行控制权直接返回到调用 f 的那个点上。
消除:在尾调用之后,程序不需要保存任何关于该函数的栈信息了,使得在进行尾调用时不耗费任何栈空间。

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

 g()  -- g()是函数f的最后调用
end

编译、执行、错误

32、编译:区分解释型语言的主要特征不是能否去编译它们,而是在编译器是否是运行时库的一部分,是否有能力执行动态生成的代码。

dofile:实际是调用loadfile,从文件加载lua代码,编译并运行,会引发错误

loadfile:从文件加载lua代码,编译但不运行(编译成函数,作为匿名函数返回),不会引发错误,有错误时只是返回错误值
源代码 foo.lua

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

运行:

f = loadfile("foo.lua") --只是返回了函数,但没有执行
print(foo)    --nil
f()               --定义foo函数
foo("ok")    --ok

load(低版本中是loadstring):从一个字符串读取代码,返回一个函数。(比直接定义函数写代码慢得多)

i = 32
local i = 0
f = load("i = i+1;print(i)") --load总是在全局环境中编译的,所以这里访问到的i是全局变量i
g = function() i = i+1;print(i) end

f()
g()

--输出 33  1

33、C代码:需要使用前先链接入应用程序
loadlib函数加载指定的库,并将其链接入Lua:将C函数作为Lua函数返回

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

34、错误(error):只要发生错误,Lua就会结束当前程序块并返回应用程序
error

if not n then
error("invalid input") --显示抛出错误信息
end

assert(p1, p2):如果p1为true,就简单返回该参数,否者引发一个错误。p2是错误信息,可选

35、错误处理和异常:pcall(protected call)来包装需要执行的代码,捕获函数执行中任何错误。

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

local status, err = pcall(fun)
if status then
 --运行fun时没有发生错误
 print("not have error")
else
 --错误处理代码
 print("have error")
 print(err) --只要错误消息是字符串,Lua就会附加一些错误发生位置的信息
end
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,042评论 6 490
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 89,996评论 2 384
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,674评论 0 345
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,340评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,404评论 5 384
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,749评论 1 289
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,902评论 3 405
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,662评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,110评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,451评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,577评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,258评论 4 328
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,848评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,726评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,952评论 1 264
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,271评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,452评论 2 348

推荐阅读更多精彩内容