学习到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. LN : leetcode 53 Maximum Subarray

    lc 53 Maximum Subarray 53 Maximum Subarray Find the contiguous subarray within an array (containing ...

  2. Code Kata:大整数四则运算—乘法 javascript实现

    上周练习了加减法,今天练习大整数的乘法运算. 采取的方式同样为竖式计算,每一位相乘后相加. 乘法函数: 异符号相乘时结果为负数,0乘任何数都为0 需要调用加法函数 因为输入输出的为字符串,需要去除字符 ...

  3. Android Studio3.0打包APK的时候 报错:

    Error:Execution failed for task ':app:transformDexWithDexForRelease'.> com.android.build.api.tran ...

  4. android 蓝牙开发---与蓝牙模块进行通讯 基于eclipse项目

      2017.10.20 之前参加一个大三学长的创业项目,做一个智能的车锁App,用到嵌入式等技术,App需要蓝牙.实时位置等技术,故查了几篇相关技术文章,以此参考!             //先说 ...

  5. Hibernate框架之HQL查询与Criteria 查询的区别

    Hibernate框架提供了HQL查询和Criteria 查询.下面对这两种查询分别做个例子.也好对这两种查询方法有个大概的了解.就用房屋信息表做例子,查询所有房屋信息. HQL语句查询所有房屋信息: ...

  6. parsley.js验证的基本引用

    前段时间看到博客有些parsley.js验证,只是对parsley.js验证框架基本的应用,对parsley.js更深层理解没有介绍和demo 比如:异步请求,扩展验证的写法,我把我学到的parsle ...

  7. CAD设置背景图片

    把图片作为背景图片可见但是不能编辑操作. 主要用到函数说明: _DMxDrawX::DrawImageToBackground 绘光栅图到背景.详细说明如下: 参数 说明 BSTR sFileName ...

  8. 折线分割平面(hdoj 2050,动态规划递推)

    Problem Description 我们看到过很多直线分割平面的题目,今天的这个题目稍微有些变化,我们要求的是n条折线分割平面的最大数目.比如,一条折线可以将平面分成两部分,两条折线最多可以将平面 ...

  9. Socket中BufferedReader.readLine()的阻塞特性导致的数据无法多次发送的问题

    https://blog.csdn.net/shenpibaipao/article/details/70236657

  10. 洛谷——P2261 [CQOI2007]余数求和

    P2261 [CQOI2007]余数求和 关键在于化简公式,题目所求$\sum_{i=1}^{n}k\mod i$ 简化式子,也就是$\sum_{i=1}^{n}(k-\frac{k}{i}\time ...