美文网首页Lua教程
Lua极简入门(六)——函数的参数

Lua极简入门(六)——函数的参数

作者: 李小磊_0867 | 来源:发表于2019-10-27 21:11 被阅读0次

    函数定义完成后,那么函数的调用方式,完成的功能,以及返回值都将固定。此时就剩下调用了,对于调用函数,只需要关注参数,并按要求设置参数,并接收返回值,这样函数的整个流程就完成了。

    在Lua中,支持可变参数定义,即在函数使用过程中,传递的参数是可以变化的,可不传、传递一个、两个等等。比如需要计算一组数字的累加,那么数字的个数是不固定的。通常会定义一个函数,接收一个table,将不固定的数字存储到table中,并作为实参传入到函数中,实现累加需求:

    function adds(numbers)
        total = 0
        for i, v in pairs(numbers) do
            total = total + v
        end
    
        return total
    end
    

    函数定义完成后,在使用之前,先将数字添加到一个table中,之后完成调用

    nums = { 1, 2, 3 }
    t = adds(nums)
    print(t)
    -->> 6
    nums = { 1, 2, 3, 4 }
    t = adds(nums)
    print(t)
    -->> 10
    

    以上按传统的方式实现了不固定数字的累加函数定义。对于Lua,可以使用可变参数的定义方法,完成不固定数字累加的方法,这种实现及调用时更加方便,毕竟不用在声明table并组织参数:

    function adds(...)
        total = 0
        for i, v in pairs({ ... }) do
            total = total + v
        end
    
        return total
    end
    

    上面Lua的可变参数定义,与传统函数(参数为table)定义方式相比,基本上一致,只是将参数table变更为了...三个点。虽然函数定义时,没有太大变化,但是在调用时,将完全不同。

    print(adds())
    -->> 0
    print(adds(1, 2, 3))
    -->> 6
    print(adds(1, 2, 3, 4))
    -->> 10
    

    参数中的3个点... 表示该函数可接受不同数量的参数。当调用时,所有的参数都会被收集起来,当访问可变参数时,仍然使用3个点表示,...在使用时,作为一个表达式,如上述中的{...},当使用{}标记可变参数时,则将其转换为了一个table

    三个点...作为表达式,可以在函数中直接使用,但在使用时,会将所有的可变参数全部返回。

    function adds(...)
        local a, b = ...
        print(a, b)
    end
    
    adds(1, 2)      -- 读取可变参数,并赋值给a,b
    -->> 1  2
    adds(3, 4, 5)   -- 读取可变参数,并赋值给a,b,5将会被丢弃
    -->> 3  4
    

    在定义函数过程中,可变参数也可以和固定位置的参数混用,但可变参数必须在最后位置。

    function adds(name, ...)
        if name ~= nil then
            print("name=" .. name)
        end
        print(...)
    end
    
    adds()          -- name 和 可变参数均为nil
    adds(1)         -- name=1,可变参数为nil
    -->> name=1
    adds(1, 2, 3)   -- name=1,可变参数为2,3
    -->> name=1
    -->> 2  3
    

    在前面,已经使用可变参数...作为表达式,将其值全部返回,并赋给新的变量;也可以将可变参数转为数组{...},并遍历使用可变参数。Lua在这两种读取可变参数之外,还提供了select函数,用于访问变长参数。该函数的定义方式为select(index,...),即第一个位置为固定参数,值包含两种取值:number#,如果传递数值,则表示获取可变参数指定位置的参数,如果为#,则返回可变参数的长度;第二个参数为可变参数本身,仍使用...表示。

    function adds(...)
        for i, v in pairs({ ... }) do
            print(v)
        end
    end
    adds(1, 2, nil, 4)
    -->> 1
    -->> 2
    -->> 4
    

    上述中,无法使用table获取到传递的nil。为了解决这个问题,可以使用select以便获取参数总长度,以及指定位置的参数。

    function adds(...)
        local i = select(2, ...)
        print(i)
        local i = select(3, ...)
        print(i)
        local len = select("#", ...)    -- 获取可变参数的长度
        print(len)
    end
    
    adds(1, 2, nil, 4)
    -->> 2
    -->> nil
    -->> 4
    

    可变参数,在使用过程中,当作为表达式时,完全等价于原始可变参数,因此可变参数,在一些需要记录日志时,有着非常良好的应用场景,比如类似于Spring切面记录日志的方式,可以使用Lua的可变参数来进行模拟

    function adds(...)
        total = 0
        for i, v in pairs({...}) do
            total = total + v
        end
    
        return total
    end
    
    function log(...)
        print("执行累加操作")
        return adds(...)
    end
    
    t = log(adds(1, 2, 3, 4))
    print(t)
    -->> 执行累加操作
    -->> 10
    

    在Python中,有一种关键词参数,在调用时允许使用关键字对参数进行限定,并提供必要的检查手段,对于程序的扩展,有着良好的作用,如下:

    def call(name,**kw):
        pass
    
    call("ray", language='java', position='beijing')
    

    在Lua中,并不具备命名参数的功能,但是可以使用table进行模拟实现,并且当参数只有一个时,Lua允许直接跟table,因此从实用上可以实现类似的效果。

    function worker(employee)
        -- 必须具备姓名,开发语言,以及工作年限
        if not employee.name or type(employee.name) ~= "string" then
            error("员工必须具备姓名")
        end
        if type(employee.language) ~= "string" then
            error("必须具备开发语言")
        end
        if type(employee.workingYears) ~= "number" then
            error("需要工作年限")
        end
        -- 还有其他属性,如籍贯省市,月薪等
        print(employee.province)
        print(employee.city)
        print(employee.salary)
    end
    
    worker{
        name = "ray",
        language = "java",
        workingYears = 10,
        province = "beiijng",
        city = "beijing"
    }
    

    相关文章

      网友评论

        本文标题:Lua极简入门(六)——函数的参数

        本文链接:https://www.haomeiwen.com/subject/pzpmvctx.html