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编程中。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2025-01-05 22:48:52

lua的函数初识的相关文章

lua闭合函数

function count( ... ) local i = 0 return function( ... ) i = i+ 1 return i end end local func = count(...) print(func()) print(func()) print(func()) 结果如下: 1 2 3 [Finished in 0.1s] lua 闭合函数:一个函数加上该函数所需访问的所有“非局部变量”. 如上所示:count()函数返回了另一个函数,而这个函数使用了count

Lua程序设计 函数 正确的尾调用

Lua中的"尾调用"就是一种类似于goto的函数调用,当一个函数调用是另一个函数的最后一个动作时,该调用才算是一条"尾调用".[一个函数在调用完另一个函数之后,是否就无其他事情需要做了] function f(x) return g(x) end   也就是说,当f调用完g之后,f所代表的整个函数的调用才算执行完成也就无其他事情可做了.因此,这种情况中,程序就不需要返回那个"尾调用"所在的函数了. 所以在"尾调用"之后,程序也

VC和LUA混合开发之VC程序调用Lua脚本函数

http://www.cnblogs.com/clever101/archive/2010/04/14/1712207.html 作者:朱金灿 来源:http://www.cnblogs.com/clever101/ Lua语言以其卓越的可扩展性.简单.高效率和与平台无关性在游戏领域得到广泛应用.今天花了一些时间学习VC和Lua如何混合开发,编写了一个小例程,和大家分享一下这方面的经验. 首先在http://www.lua.org/ftp/下载Lua的最新版本:lua-5.1.4.然后用VS C

Lua function 函数

Lua支持面向对象,操作符为冒号‘:’.o:foo(x) <==> o.foo(o, x). Lua程序可以调用C语言或者Lua实现的函数.Lua基础库中的所有函数都是用C实现的.但这些细节对于lua程序员是透明的.调用一个用C实现的函数,和调用一个用Lua实现的函数,二者没有任何区别. 函数的参数跟局部变量一样,用传入的实参来初始化,多余的实参被丢弃,多余的形参初始化为nil. count=0 function incCount(n) n=n or 1 count=count+n end i

Lua中函数

1,lua中函数属于“第一类值”(与其他传统类型值具有相同的权利),函数可以存贮到变量或table中,可以作实参和其他函数返回值 2,函数与其他值一样都是匿名的,它们都没有名称,所谓的函数名实际上是一个持有某函数的变量 function foo (x) return 2*x     end 是这种方式的简写 foo = function (x)  return 2*x     end 3,closure(闭合函数) function newCounter() local i = 0 return

lua中函数简介

在lua中,函数是一种第一类值,它们具有特定的词法域. 第一类值表示在lua中函数与其他传统类型的值具有相同的权利.函数可以存储在变量中,全局变量或者拒不变量或者table中,可以作为实参传递给其他函数,还可以作为其他函数的返回值. 词法域是什么意思呢,这是指一个函数可以嵌套在另一个函数中.内部的函数可以访问外部函数中的变量.接下来就会看到,这项听似平凡的特性将给语言带来极大的能力.因为它允许在Lua中应用各种函数式语言中的强大编程技术. 在lua中有一个容易混淆的概念是,函数与所有其他值一样都

lua常用函数

select (index, ···) 功能:当index为数字将返回所有index大于index的参数: 如:select(2,"a","b","c") 返回 "b","c" 当index为"#",则返回参数的总个数(不包括index) 如:select("#","a","b","c") 返回 3 lua常

Lua 常用函数 一

http://blog.csdn.net/xuzhonghai/article/details/7239195 lua_getallocf lua_Alloc lua_getallocf (lua_State *L, void **ud); 返回给定状态机的内存分配器函数.如果 ud 不是 NULL ,Lua 把调用lua_newstate 时传入的那个指针放入*ud . lua_getfenv void lua_getfenv (lua_State *L, int index); 把索引处值的

CCLayer注册lua回调函数setTouchPriority失效

CCLayer注册lua回调函数setTouchPriority失效: 方式1.不行 touchLayer:setTouchPriority(-5000) touchLayer:registerScriptTouchHandler(touchLayerCallFunc) touchLayer:setTouchEnabled(true) maskLayer:addChild(touchLayer) 方式2.可以 touchLayer:registerScriptTouchHandler(touch