《Lua程序设计[第二版]》第5,6章笔记

第5章表达式

Lua的函数一般将参数放到函数名后的圆括号中。特殊情况:一个函数只有一个参数,并且该参数是一个字符串或table构造式,那么圆括号可有可无,例如:

print “Hello World”        --     print(“HelloWorld”)
dofile ‘a.lua’             --     dofile(‘a.lua’)
print [[a melti-line         --     print([[amulti-line
       message]]                            message]])
f {x=10, y=20}               --     f({x=10,y=20})
type {}                      --     type({})

Lua提供了冒号操作符。表达式o.foo(o,x)的另一种写法是o:foo(x),冒号操作符使调用o.foo时将o隐含地作为函数的第一个参数。

Lua程序中既可以使用Lua编写的函数,也可以调用用C语言写的函数。

Lua函数遵循“若实参多余形参,则舍弃多余的实行;若实参不足,则将多余的形参初始化为nil”的规则。假设有如下函数:

function f(a, b) return a or b end

则以下几种调用,实参与形参的对应关系为:

f(3)                -- a = 3,  b =nil

f(3, 4)            -- a = 3,  b = 4

f(3, 4, 5)        -- a = 3,  b = 4  (5被丢弃)

5.1多重返回值(multiple result)

Lua具有一项非常与众不同的特征,允许函数返回多个结果。例如,用于在字符串中定位一个模式的函数string.find。若该函数在字符串中找到了指定的模式,将返回匹配的起始字符和结尾字符的索引,这样就需要使用多重赋值语句来接受函数的返回值。

用户自定义的函数同样可以返回多个结果,例如:

function maximum(a)
local mi = 1           --最大值的索引
local m = a[mi]        -- 最大值
for i, var in ipairs(a) do
       ifvar > m then
              mi= i; m = var
       end                --end if
end                       -- endfor
 
return m, mi
end                       -- endfunction
 
print(maximum({8, 10, 23, 12, 5}))

一个函数具有多个返回值时,例如:functionfoo() return “a”, “b” end

在语句print(foo().. “x”)中,打印结果为ax。因为函数foo出现在一个表达式中,Lua将其返回值数量调整为1,用于参与字符串连接操作。

table构造式可以完整的接受一个函数返回的所有值:t = {foo()} 即 t = {“a”, “b”}

但若一个table接受多个函数时,只有最后一个函数的返回值全部接受,其余的每个函数只接受一个值:t= {foo(), foo()}  -- t = {“a”, “a”, “b”}

Lua的预定义函数unpack,它接受一个数组作为参数,并从下标1开始返回该数组内的所有元素。原函数由C语言实现的,也可以通过递归实现一样的效果:

function unpack (t, i)
       i= i or 1
       ift[i] then
              returnt[i], unpack(t, i+1)
       end
end
 
a = {"My","name", "is", "Lua."}
 
print(unpack(a))

5.2变长参数(variable number of arguments)

Lua中的函数可以接受不同数量的实参。用三个点(…)表示该函数可以接受不同数量的实参。一个函数要访问它的变长参数时,仍需用到3个点(…)。例如:

function add (...)
local s = 0
       fori, v in ipairs{...} do
              s= s + v
       end
       returns
end
 
print(add(3, 4, 10, 25, 12))    -- 54

5.3具名实参(named arguments)

函数os.rename用于文件名改名,如:os.rename( {old=”temp.lua”, new=”temp1.lua”} )。

 


第6章深入函数

在Lua中,函数是一种“第一类值(First-Class Value)”,这表示在Lua中函数与其他传统类型的值(例如字符串和数字)具有相同的权利。函数可以存储到变量中或table中,可以作为实参传递给其他函数,还可以作为其他函数的返回值。

6.1closure(闭合函数)

在Lua中,一个函数可写在另一个函数里,内部函数可以访问外部函数中的局部变量。

6.2非全局的函数(non-global function)

将一个函数存储到一个局部变量中,即得到了一个“局部函数(local function)”。

6.3正确的尾调用(proper tail call)

所谓的“尾调用(tail call)”就是一种类似于goto的函数调用。当一个函数调用是另一个函数的最后一个动作时,该调用才算是一条“尾调用”,例如:

function  f(x)  return  g(x)  end

中的g函数就是一条“尾调用”。在这种情况中,程序不需要返回那个“尾调用”所在的函数。所以在“尾调用”之后,程序也不需要保存任何关于该函数的栈(stack)信息了。当g返回时,执行控制权可以直接返回到f函数。使得在进行“尾调用”时不耗费任何栈空间。将这种现象称为“尾调用消除”。

 

 

第7章… 请看该系列的下一篇


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值