zoukankan      html  css  js  c++  java
  • 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编程中。

  • 相关阅读:
    ZOJ 3765 Lights (zju March I)伸展树Splay
    UVA 11922 伸展树Splay 第一题
    UVALive 4794 Sharing Chocolate DP
    ZOJ 3757 Alice and Bod 模拟
    UVALive 3983 捡垃圾的机器人 DP
    UVA 10891 SUM游戏 DP
    poj 1328 Radar Installatio【贪心】
    poj 3264 Balanced Lineup【RMQ-ST查询区间最大最小值之差 +模板应用】
    【转】RMQ-ST算法详解
    poj 3083 Children of the Candy Corn 【条件约束dfs搜索 + bfs搜索】【复习搜索题目一定要看这道题目】
  • 原文地址:https://www.cnblogs.com/mthoutai/p/7118629.html
Copyright © 2011-2022 走看看