学习到Lua的函数。认为有必要记下来。

參考教程:Programming in Lua

函数能够以表达式陈述语句出现,例如以下所看到的:

  print(8*9, 9/8)
a = math.sin(3) + math.cos(10)

书写函数时有个小规则,假设函数仅仅有一个參数。或者是一串字符。或者是一个表结构时。括号能够省略:

   print "Hello World" <--> print("Hello World")
dofile 'a.lua' <--> dofile ('a.lua')
f{x=10, y=20} <--> f({x=10, y=20})
type{} <--> type({})

对于Lua的面向对象,有一个特殊的语法来使用函数,就是使用冒号:

o:foo(x)

lua函数的一般写法:

    function fun_name(<parameters>)
<body>
end

举个样例:

    -- add the elements of sequence 'a'
function add (a)
local sum = 0
for i = 1, #a do
sum = sum + a[i]
end
return sum
end

调用Lua函数时,传递的參数和实际參数数目能够不一样,Lua会自己主动调整參数匹配。

假设传递的參数比实际參数多了,那么多于的会被舍弃。少于的会得到nil值。

比方有个函数有以下几种情况:

    f(3) --> 3 nil
f(3, 4) --> 3 4
f(3, 4, 5) --> 3 4 (5 is discarded)

这个特性能够被用来设置參数的默认值:

    function incCount (n)
n = n or 1
count = count + n
end

lua的函数能够有多个返回值

比方lua库函数string.find:

    s, e = string.find("hello Lua users", "Lua")
print(s, e) --> 7 9

lua函数的返回值数目也能够依据函数实际调用情况进行调整

比方以下三个函数:

function foo0 () end -- returns no results
function foo1 () return "a" end -- returns 1 result
function foo2 () return "a", "b" end -- returns 2 results

多重赋值时。要依据函数的调用位置来决定返回值的数目。函数调用在表达式末尾。则依据实际情况返回结果值。

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

无返回值或返回值数目小于多重赋值数目,则多于的值为nil。

x,y = foo0() -- x=nil, y=nil
x,y = foo1() -- x="a", y=nil
x,y,z = foo2() -- x="a", y="b", z=nil

假设函数调用不是在表达式的末尾,那么函数仅仅返回一个结果值。

x,y = foo2(), 20 -- x="a", y=20
x,y = foo0(), 20, 30 -- x=nil, y=20, 30 is discarded

当一个函数调用是另外一个函数的最后一个參数。那么第一个函数返回的全部结果都是还有一个函数的參数。

print(foo0()) -->
print(foo1()) --> a
print(foo2()) --> a b
print(foo2(), 1) --> a 1
print(foo2() .. "x") --> ax (see next)

表构造能收集函数的全部返回值。不须要做出调整。

t = {foo0()} -- t = {} (an empty table)
t = {foo1()} -- t = {"a"}
t = {foo2()} -- t = {"a", "b"}

当然,这也仅仅是针对函数处于表达式的末尾时:

t = {foo0(), foo2(), 4} -- t[1] = nil, t[2] = "a", t[3] = 4

形如return f()这个表达式也会返回f的全部结果值:

function foo (i)
if i == 0 then return foo0()
elseif i == 1 then return foo1()
elseif i == 2 then return foo2()
end
end
print(foo(1)) --> a
print(foo(2)) --> a b
print(foo(0)) -- (no results)
print(foo(3)) -- (no results)

当然也能够通过一个括号来仅仅返回一个结果值:

print((foo0())) --> nil
print((foo1())) --> a
print((foo2())) --> a

有个特别的函数table.unpack就是有多个返回值:

print(table.unpack{10,20,30}) --> 10 20 30
a,b = table.unpack{10,20,30} -- a=10, b=20, 30 is discarded

unpack能帮助你实现一个调用含有随意參数的随意函数机制,说白了。能实现函数的动态调用。还是看样例。

f(table.unpack(a))

这个函数将a中的全部值作为f函数的參数。

以下看这个函数调用:

print(string.find("hello", "ll"))

你能够动态的进行改写:

f = string.find
a = {"hello", "ll"}
print(f(table.unpack(a)))

通常来说,unpack使用长度运算符来确定元素的返回数目,所以它是针对适当的序列来说的。

可是假设须要。能够加以限制:

print(table.unpack({"Sun", "Mon", "Tue", "Wed"}, 2, 3))
--> Mon Tue

參数可变的函数

lua的函数能够拥有可变參数,也就是參数数目可变。print就是这样一个函数。

以下是用Lua函数实现的可变參数函数样例:

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

…这三点就是表明一个函数有可变參数。…叫做參数变量表达式。表现相似一个返回全部结果值的函数。

能够模仿函数參数传递机制:

function foo (a, b, c)

变为:

function foo (...)
local a, b, c = ...

再看:

function id (…) return … end

function foo1 (...)
print("calling foo:", ...)
return foo(...)
end

上面这个机制能够用来进行跟踪调试。

以下是另外一个实用的样例。结合string.format与io.write函数:

function fwrite (fmt, ...)
return io.write(string.format(fmt, ...))
end

注意上面的三点在fmt之后。

由于Lua函数中可变參数这部分之前能够是參数数目确定的部分。

CALL                        PARAMETERS
fwrite() fmt = nil, no extra arguments
fwrite("a") fmt = "a", no extras
fwrite("%d%d", 4, 5) fmt = "%d%d", extras = 4 and 5

有极少数情况下,可变參数中可能有nil值,这时候{…}就不适用了。

这样的情况下。就要用table.pack函数,这个函数接收随意数目參数然后返回一个新的表。可是这个表有个额外的n区域,表示元素数目。

以下的样例測试是否有參数为nil:

function nonils (...)
local arg = table.pack(...)
for i = 1, arg.n do
if arg[i] == nil then return false end
end
return true
end
print(nonils(2,3,nil)) --> false
print(nonils(2,3)) --> true
print(nonils()) --> true
print(nonils(nil)) --> false

在可变參数中不会有nil值的情况下{…}比table.pack(…)速度快多了。

命名參数

Lua中函数參数传递是基于位置的。可是。也能够通过名字来定义參数,这在某些时候非常实用,比方os.rename函数,对一个文件重命名。

通常,我们不知道哪个文件名称在前。

这是,通过名字就非常实用了:

rename{old="temp.lua", new="temp1.lua"}

function rename (arg)
return os.rename(arg.old, arg.new)
end

这样的风格的函数传递在函数有非常多參数且它们当中大部分都是可选项时是非常实用的。比方GUI编程中。

lua的函数初识的更多相关文章

  1. lua闭合函数

    function count( ... ) return function( ... ) i = i+ return i end end local func = count(...) print(f ...

  2. Lua基础 函数(一)

    转自: http://blog.csdn.net/wzzfeitian/article/details/8653101 在Lua中,函数是对语句和表达式进行抽象的主要方法.既可以用来处理一些特殊的工作 ...

  3. Lua function 函数

    Lua支持面向对象,操作符为冒号‘:’.o:foo(x) <==> o.foo(o, x). Lua程序可以调用C语言或者Lua实现的函数.Lua基础库中的所有函数都是用C实现的.但这些细 ...

  4. lua API函数大全

    Lua5.1中的API函数 lua_State* luaL_newstate()Lua脚本的编译执行是相互独立的,在不同的线程上执行.通过luaL_newstate()函数可以申请一个虚拟机,返回指针 ...

  5. lua c函数注册器

    lua与c的交互 关于lua和c的交互,主要有两个方面,一是lua调用c的函数,而另一个则是c调用lua函数.而这些都是通过lua stack来进行的. c调用lua 在c里面使用lua,主要是通过l ...

  6. 【python 3】 函数 初识

    函数初识 1.函数的定义.调用.返回值 函数的定义.调用.返回值 def demo(): ## 定义函数 (def + 空格 + 函数名 + () + 冒号) ## 如下为函数体 return a # ...

  7. day3----编码-集合-深浅copy-文件操作-函数初识

    本文档主要内容: 一 编码 二 集合 三 深浅copy 四 文件操作 五 函数初识 首先,我们来看看两个字符串的比较 打开cmd,进入dos界面 >>>a='xingchen@' & ...

  8. 《Python》 函数初识

    一.函数: 1.函数初识: def 关键字 函数名 # def my_len() 函数名的命名规则跟变量一样,要具有描述性. 函数的优点: 减少代码的重复率 增强代码的阅读性 函数的主要目的:封装一个 ...

  9. lua 二进制函数使用

    由于 Lua 脚本语言本身不支持对数字的二进制操作(例如 与,或,非 等操作),MUSHclient 为此提供了一套专门用于二进制操作的函数,它们都定义在一个"bit"表中,使用时 ...

随机推荐

  1. 关于defineProperty

    var c=0; Object.defineProperty(this,'b',{ get :function(){ return ++c; } }) console.log(b===1&&a ...

  2. windows服务器监控多个tomcat运行状态

     第一步,修改tomcat默认的进程名 因为所有的tomcat项目的进程名默认都叫java.exe,所以需要修改tomcat容器bin目录下的setclasspath.bat.注释掉:(在set前加上 ...

  3. python游戏开发:pygame事件与设备轮询

    一.pygame事件 1.简介 pygame事件可以处理游戏中的各种事情.其实在前两节的博客中,我们已经使用过他们了.如下是pygame的完整事件列表: QUIT,ACTIVEEVENT,KEYDOW ...

  4. Windows提高_2.3第三部分:内核区同步

    第三部分:内核区同步 等待函数(WaitForObject) 等待函数的形式 单个:WaitForSingleObject 多个:WaitForMultipleObjects 一个可以被等待的对象通常 ...

  5. R语言学习 - 箱线图(小提琴图、抖动图、区域散点图)

    箱线图 箱线图是能同时反映数据统计量和整体分布,又很漂亮的展示图.在2014年的Nature Method上有2篇Correspondence论述了使用箱线图的好处和一个在线绘制箱线图的工具.就这样都 ...

  6. UVA - 1601 The Morning after Halloween (双向BFS&单向BFS)

    题目: w*h(w,h≤16)网格上有n(n≤3)个小写字母(代表鬼).要求把它们分别移动到对应的大写字母里.每步可以有多个鬼同时移动(均为往上下左右4个方向之一移动),但每步结束之后任何两个鬼不能占 ...

  7. apacheAB测试指标

    在进行性能测试过程中有几个指标比较重要: 1.吞吐率(Requests per second) 服务器并发处理能力的量化描述,单位是reqs/s,指的是在某个并发用户数下单位时间内处理的请求数.某个并 ...

  8. Flask项目中整合各组件

    一.介绍 主要介绍flask_sqlalchemy.flask_script.flask_migrate这三个组件该如何整合到flask项目中,以及如何使用. # 安装组件 pip3 install ...

  9. Linux:SAMBA共享、NFS共享、Autofs自动挂载

    SAMBA.NFS共享区别 NFS开源文件共享程序:NFS(NetworkFile System)是一个能够将多台Linux的远程主机数据挂载到本地目录的服务,属于轻量级的文件共享服务,不支持Linu ...

  10. Centos6文本安装教程

    Centos6.4文本方式安装 虚拟机中文本安装(内存512),内存大于512默认为图形安装 1.选择安装媒体,在vbox中选skip跳过 2.选择安装语言(chinese(simplifired)简 ...