lua的函数初识
学习到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的函数初识的更多相关文章
- lua闭合函数
function count( ... ) return function( ... ) i = i+ return i end end local func = count(...) print(f ...
- Lua基础 函数(一)
转自: http://blog.csdn.net/wzzfeitian/article/details/8653101 在Lua中,函数是对语句和表达式进行抽象的主要方法.既可以用来处理一些特殊的工作 ...
- Lua function 函数
Lua支持面向对象,操作符为冒号‘:’.o:foo(x) <==> o.foo(o, x). Lua程序可以调用C语言或者Lua实现的函数.Lua基础库中的所有函数都是用C实现的.但这些细 ...
- lua API函数大全
Lua5.1中的API函数 lua_State* luaL_newstate()Lua脚本的编译执行是相互独立的,在不同的线程上执行.通过luaL_newstate()函数可以申请一个虚拟机,返回指针 ...
- lua c函数注册器
lua与c的交互 关于lua和c的交互,主要有两个方面,一是lua调用c的函数,而另一个则是c调用lua函数.而这些都是通过lua stack来进行的. c调用lua 在c里面使用lua,主要是通过l ...
- 【python 3】 函数 初识
函数初识 1.函数的定义.调用.返回值 函数的定义.调用.返回值 def demo(): ## 定义函数 (def + 空格 + 函数名 + () + 冒号) ## 如下为函数体 return a # ...
- day3----编码-集合-深浅copy-文件操作-函数初识
本文档主要内容: 一 编码 二 集合 三 深浅copy 四 文件操作 五 函数初识 首先,我们来看看两个字符串的比较 打开cmd,进入dos界面 >>>a='xingchen@' & ...
- 《Python》 函数初识
一.函数: 1.函数初识: def 关键字 函数名 # def my_len() 函数名的命名规则跟变量一样,要具有描述性. 函数的优点: 减少代码的重复率 增强代码的阅读性 函数的主要目的:封装一个 ...
- lua 二进制函数使用
由于 Lua 脚本语言本身不支持对数字的二进制操作(例如 与,或,非 等操作),MUSHclient 为此提供了一套专门用于二进制操作的函数,它们都定义在一个"bit"表中,使用时 ...
随机推荐
- 推荐一些相见恨晚的 Python 库 「一」
扯淡 首先说明下,这篇文章篇幅过长并且大部分是链接,因此非常适合在电脑端打开访问. 本文内容摘自 Github 上有名的 Awesome Python.这是由 vinta 在 14 年发起并持续维护的 ...
- Windows sever 2003 IIS6.0 搭建DVWA
DVWA 环境: Windows Sever 2003 IIS 6.0+MYSQL+PHP5.4+FASFCGI 详细教程: http://files.cnblogs.com/files/yyx001 ...
- unittest自定义运行全量case or 运行指定的单个或多个case
import unittest import os from case.zufang.test_api_area_rentProlist import Zf1 case_path = os.path. ...
- oracle_backup
#!/bin/bash DAYS=`date +"%Y%m%d"` . /home/oracle/.bash_profile # /home/opt/oracle/11g/bin/ ...
- 14: curl#6 - "Could not resolve host: mirrorlist.centos.org; 未知的错误"
14: curl#6 - "Could not resolve host: mirrorlist.centos.org; 未知的错误" One of the configured ...
- returnValue of Chrome
说实话,我一看到这个returnValue就有点反感,感觉这个就是IE式的老套的用法,因为项目中有用到就了解了下,以下主要是一些我的理解和发现吧. PS:returnValue是window的属性,s ...
- mysql外键是多个id组成的字符串,查询方法
借鉴:mysql使用instr达到in(字符串)的效果 结论:select * from 表名where INSTR(CONCAT(字符串),CONCAT(表id)) 问题来源:一表中的某字段是另一表 ...
- 通过docker-composer启动容器nginx,并完成spring.boot的web站点端口转发
前面已经讲过2篇基于docker的mysql.redis容器编排并启动.这次将练习下nginx的docker方式的部署,以及通过nginx去代理宿主主机上的Web服务应该怎么配 PS:(这里由于ngi ...
- Java对象序列化为什么要使用SerialversionUID
1.首先谈谈为什么要序列化对象 把对象转换为字节序列的过程称为对象的序列化. 把字节序列恢复为对象的过程称为对象的反序列化. 对象的序列化主要有两种用途: 1) 把对象的字节序列永久地保存到硬盘上,通 ...
- vue SSR 部署详解
先用vue cli初始化一个项目吧. 输入命令行开始创建项目: vue create my-vue-ssr 记得不要选PWA,不知为何加了这个玩意儿就报错. 后续选router模式记得选 histor ...