在Lua中函数的调用方式和C语言基本相同,如:print("Hello World")和a = add(x, y)。唯一的差别是,如果函数只有一个参数,并且该参数的类型为字符串常量或table的构造器,那么圆括号可以省略,如print "Hello World"和f {x = 20, y = 20}。
    Lua为面对对象式的调用也提供了一种特殊的语法--冒号操作符。表达式o.foo(o,x)的另一种写法是o:foo(x)。冒号操作符使调用o.foo时将o隐含的作为函数的第一个参数。
    Lua中函数的声明方式如下:

  1. function add(a)
  2. local sum = 0
  3. for i, v in ipairs(a) do
  4. sum = sum + v
  5. end
  6. return sum
  7. end

1. 多重返回值(multiple results)

Lua允许函数多个结果

例如

  1. s,e = string.find("hello lua world","lua")
  1. function fun()
  2. a="world"
  3. b="hello"
  4. return a,b
  5. end
  6.  
  7. i,j=fun()
  8. print(i,j)

如果函数没有返回值或者没有足够多的返回值,那么Lua用nil来填充

  1. x,y,z=fun()
  2. z的值是nil

如果一个函数调用不是一系列的表达式的最后一个元素,那么将只产生一个值:

  1. x,y=fun(),
  2. -- x="hello" y=20
  3. --fun() 返回 2个值"hello" "world"

强制返回一个元素加括号(fun())

  1. > function fun() a="hello" b="world" return a,b end
  2. > print((fun()))
  3. hello

最后一个需要介绍的是Lua中unpack函数,该函数将接收数组作为参数,并从下标1开始返回该数组的所有元素。如:

  1. > print(unpack{10,20,30})
  2. 10 20 30

unpack函数一个重要用途体现在泛型调用机制中。泛型调用机制可以动态以任何实参来调用函数。

关于unpack的使用请查看 http://www.cnblogs.com/corolla/p/3811793.html

  1. function fun(a,b)
  2. if a>b then
  3. print(a)
  4. else
  5. print(b)
  6. end
  7. end
  8. tb={,}
  9. fun(unpack(tb))

当tb表的数量过多时

  1. tb={,,}
  2. fun(unpack(tb))

2. 变长参数

Lua中的函数可以接受不同数量的实参,查看以下例子:

  1. function add(...)
  2. local s =
  3. for i,v in ipairs(...) do
  4. s = s+v
  5. -- print(v)
  6. end
  7. return s
  8. end
  9. tb={,,,}
  10. print(add(tb))

local a,b = ...类似于一个具有多重返回值的函数

  1. > function fun(...) local a,b=... print(a,b) end
  2. > fun(,)

访问变长...参数,使用select函数,访问{...}和访问table一样。select{"#",...}取参数总数,local arg = select{i,...}访问第i个。遍历的例子如下

  1. function fun(...)
  2. local s=
  3. n = select("#",...)
  4. for i=, n do
  5. local arg=select(i,...)
  6. s = s+arg
  7. end
  8. return s
  9. end
  10.  
  11. tb={,,,}
  12. print(fun(unpack(tb)))

3. 具名实参:

Lua中的参数传递机制是具有“位置性”的,也就是调用函数时,实参和形参必须一一对应。Lua并不直接支持这种语法,但可以通过一种细微的改变来获取相同的效果。主要是将所有实参组织到一个table中,并将这个table作为唯一的实参传给函数。

  1. tb={old="temp.lua",new="new.lua"}
  2. function rename(arg)
  3. return os.rename(arg.old,arg.new)
  4. end
  5. rename(tb)

如果一个函数有大量的参数,其中大部分是可选的时候,具名参数传递的方法非常有用。

深入理解函数

Lua中函数是一种“第一类值”,它们具有的特定的词法域(Lexical  Scoping)

“第一类值”表示Lua函数与其他的传统的值具有相同的权利。函数可以存储到变量中或table中。也可以作为实参传递给其他函数,也可以作为其他函数的返回值。

“词法域”是值一个函数可以潜逃在另一函数中,内部的函数可以访问外部函数中的变量。

在Lua中有一个容易混淆的概念是,函数与所有其他值一样都是匿名的,即他们都没有名称。函数名实际上是某函数的变量,与其他变量持有各种值是一个道理。

  1. > tb={p=print}
  2. > tb.p("hello world")
  3. hello world
  4. > print = math.sin --print==sin函数
  5. > tb.p(print())
  6. 0.8414709848079

4. 闭合函数(closure)

若将一个函数写在另一个函数之内,那么这个位于内部的函数便可以访问外部函数中的局部变量

  1. newCounter = function(add)
  2. local i = ;
  3. counter = function()
  4. i = i + add
  5. return i
  6. end
  7. return counter
  8. end
  9. c1 = newCounter()
  10. print(c1())
  11.  
  12. print(c1())
 
  • lua中的函数是“第一类值”,就是说函数和整数,字符串这些是一样的,都可以保存到变量中,看上面第一句的声明。
  • 初看上去,由于创建变量i的函数newCounter已经返回,所以之后每次调用匿名函数时,i都应是超出作用返回的。其实不然,Lua以closure概念处理这种情况,一个closure就是一个函数加上它访问的所有“非局部的变量”。上例中内部函数counter 的非局部变量就是i和参数add,不管c1访问多少次,都能取到这些非局部变量的值。
 

5. 非全局函数

6. 真确的尾调用(tail call)

Lua函数有一个特点:那就是Lua支持“尾调用消除” :尾调用消除就是一种类似于goto的函数调用。当一个函数f末尾调用其他函数g时,称为“尾调用”。也就说,当调用完g之后,f函数没有其他代码需要执行。这种情况,程序也不需要保存任何关于改函数的栈(stack)信息了。lua语言的尾调用不消耗任何的栈空间。

由于Lua函数尾调用不会消耗栈空间,所以一个程序可以拥有无限潜逃的尾调用。

  1. function f(x) g(x) end --不算,g(x)后需要舍弃临时结果
  2. return g(x)+ --必须做一次加法
  3. return x or g(x) --必须调整为一个返回值
  4.  
  5. 正确的尾调用:
  6. return <function>(<args>)

没有“尾调用消除”的话,每次调用都会创建一个新的栈层(stack level).

Lua学习(4)——函数的更多相关文章

  1. lua学习之函数篇

    函数 函数是对语句和表达式进行抽象的主要机制 两种用法 一是可以完成特定的任务,一句函数调用被视为一条语句 二是以只用来计算并返回特定的结果,视为一句表达式 print("Hello, Wo ...

  2. Lua 学习 chapter30 编写c函数的技巧 - Jow的博客

    目录 数组操作 字符串操作 在c函数中保存状态 生活总需要一点仪式感,然后慢慢的像那个趋向完美的自己靠近. 数组操作 Lua中的数组就是以特殊的方式使用边.像lua_setttable and lua ...

  3. Lua 学习笔记(五)函数

    函数的定义:在Lua中,函数是一种对语句和表达式进行抽象的主要机制. 一.函数基本用法        在Lua中,      1.函数既可以完成某项特定的任务.(被视为一条语句)      2.也可以 ...

  4. lua操作常用函数学习一

    (1)lua 和 C++之间的交互的基本知识: lua 和 C++ 之间的数据交互通过堆栈进行,栈中的数据通过索引值进行定位,(栈就像是一个容器一样,放进去的东西都要有标号)其中栈顶是-1,栈底是1, ...

  5. Lua学习笔记(三):函数和闭包

    函数 lua的函数以function关键字开始,后跟函数名称和参数,最后以end结束,我们看一个简单的函数定义: function foo() --do something end function ...

  6. Lua学习笔记(6): 函数

    Lua的函数 函数用于简化程序,当某些工作需要重复执行的时候就可以使用函数减轻工作量(虽然复制粘贴也行) 语法: function 函数名(参数列表) 函数体 return 返回值 end --结束标 ...

  7. Lua 学习之基础篇二<Lua 数据类型以及函数库 汇总>

    引言 前面讲了运算符,这里主要对Lua的数据处理相关的数据类型和函数库进行总结归纳,后面会再接着单独分开讲解具体使用. 首先因为Lua 是动态类型语言,变量不要类型定义,只需要为变量赋值. 值可以存储 ...

  8. [转]LUA 学习笔记

    Lua 学习笔记 入门级 一.环境配置 方式一: 1.资源下载http://www.lua.org/download.html 2.用src中的源码创建了一个工程,注释调luac.c中main函数,生 ...

  9. Lua学习笔记(二):基本语法

    Lua学习指南:http://www.lua.org/manual/ 首先我们要明确的一点是:在Lua中,除了关键字外一切都是变量. Lua关键字 可以查看这个地址:http://www.lua.or ...

随机推荐

  1. Sphinx安装流程及配合PHP使用经验

    1.什么是Sphinx Sphinx是俄罗斯人Andrew Aksyonoff开发的高性能全文搜索软件包,在GPL与商业协议双许可协议下发行. 全文检索式指以文档的全部文本信息作为检索对象的一种信息检 ...

  2. java基础之类与对象3

    前面我的两篇文章主要介绍了将怎么将事物抽象为对象,以及对象的实例化(就是new一个对象).这篇文章里面我就讲下匿名对象... 还是就举之前的例子把,Car c = new Car();看到这个我们就知 ...

  3. JS实现轻量级计算器

    想尝试做一个网页版计算器后,参考了很多博客大神的代码,综合归纳.总结修改,整理如下文. 附:   Demo    源码 一.HTML+CSS 具体结构样式如下图,基本参照手机计算器界面.按钮功能可以查 ...

  4. toastr.js插件用法

    toastr.js插件用法 toastr.js是一个基于jQuery的非阻塞通知的JavaScript库.toastr.js可以设定四种通知模式:成功.出错.警告.提示.提示窗口的位置.动画效果等都可 ...

  5. 微信和支付宝支付模式详解及实现(.Net标准库)- OSS开源系列

    支付基本上是很多产品都必须的一个模块,大家最熟悉的应该就是微信和支付宝支付了,不过更多的可能还是停留在直接sdk的调用上,甚至和业务系统高度耦合,网上也存在各种解决方案,但大多形式各异,东拼西凑而成. ...

  6. USACO Section 1.1-1 Your Ride Is Here

    USACO 1.1-1 Your Ride Is Here 你的飞碟在这儿 众所周知,在每一个彗星后都有一只UFO.这些UFO时常来收集地球上的忠诚支持者.不幸的是,他们的飞碟每次出行都只能带上一组支 ...

  7. PHP 魔术方法 __call 与 __callStatic 方法

    PHP 魔术方法 __call 与 __callStatic 方法 PHP 5.3 后新增了 __call 与 __callStatic 魔法方法. __call 当要调用的方法不存在或权限不足时,会 ...

  8. (function($){….})(jQuery)一种js插件写法

    我们先看第一个括号里边的内容:function($){….},这不就是一个匿名的函数吗?但是它的形参比较奇怪,是$,这里主要是为了不与其它的库冲突. 这样我们就比较容易理解第一个括号内的内容就是定义了 ...

  9. 细谈UITabBarController

    1.简述 UITabBarController和UINavigationController类似,UITabBarController也可以轻松地管理多个控制器,轻松完成控制器之间的切换,UITabB ...

  10. Extjs6组件——Form大家族成员介绍

    本文基于ext-6.0.0 一.xtype form一共有12种xtype,下面来一一举例说一下. 1.textfield 这个是用的最多的form之一. { xtype: 'textfield', ...