zoukankan      html  css  js  c++  java
  • Lua小技巧

    Lua小技巧

    来源 https://segmentfault.com/a/1190000000409668

    命令行参数

    命令行参数存储在arg表中,假定你有一个foo.lua脚本:

    print(arg[-1], arg[0])
    for i, v in ipairs(arg) do print(v) end
    

    假设我们运行lua foo.lua arg1 arg2 arg3,输出为:

    lua foo.lua
    arg1
    arg2
    arg3
    

    文件中的...

    由于文件以函数的方式加载,所以我们可以用上...。假定bar.lua内容如下:

    print(...) -- 输出所有传递给该文件函数的参数
    

    以如下语句加载:

    loadfile("bar.lua")(1, 2, 3, 4)
    

    输出为1 2 3 4.

    dofile不发送参数,require发送给定的路径:

    require("bar") -- "bar"
    require("folder.subfolder.bar") -- "folder.subfolder.bar"
    

    如果你运行lua bar.lua arg1 arg2 arg3,会输出arg1 arg2 arg3

    _G

    里面存了所有的全局变量:

    a = 3
    print(_G.a) -- 3
    _G.b = 4
    print(b) -- 4
    print(_G._G == _G) -- true

    来源 https://segmentfault.com/a/1190000004200022

    局部变量和全局变量

    如果为了更严格的使用局部变量,可以用do-end来界定一个块。即在do之后end之前组成一个作用域。

    do
        local a = 10
        ...
    end
    print( a )  -- nil

    Lua中这个全局变量本质上也是一个table, 它把我们创建的全局变量都保存在一个table里了。这个table名为_G。所以我们可以这样返回全局变量:

    print( _G["myGlobal"] )  -- 这个全局名当然可以是其他类型
    print( _G.myGlobal )

    unpack

    在多重返回值中,unpack,它接受一个数组为参数,它返回下标为1开始的所有元素。

    local function Foo(a, b)
        print(a, b)
    end
    local tab = {1,2}
    Foo(unpack(tab))  -- 1,2

    变长参数

    function add(...)
        local s = 0
        for i, v in ipairs{...} do
            s = s + v
        end
        return s
    end
    print( add(2,3,3) )  -- 8

    参数表三个点表示可接受不同数量的实参。

    具名实参

    function Add(options)
        if type(options.num1) ~= "number" or type(options.num2) ~= "number" then
            error("Add parameter are not number type")
        end
        print(options.num1, options.num2)
    end
    
    Add{num2=5,num1=4}  -- 使用具名实参

    匿名函数与闭包

    foo = function (x) return 2*x end  -- 匿名函数
    
    -- 使用匿名函数增加便捷性
    table.sort( network, function (a,b) return a.name > b.name end )
    
    -- 用闭包实现一个计数函数
    function newCounter()
        local iCount = 0
        return function () iCount = iCount + 1 return iCount end
    end
    
    c1 = newCounter()
    print( c1() )  -- 1
    print( c1() )  -- 2
    c2 = newCounter()
    print( c2() )  -- 1
    print( c1() )  -- 3
    print( c2() )  -- 2
    
    -- 闭包实现迭代器(更准确说是生成器)
    function next(t)
        local i = 0
        return function () i = i + 1; return t[i] end
    end
    
    t = {1,2,10}
    iter = next(t)
    while true do
        local elem = iter()
        if elem == nil then break end
        print(elem)
    end
    
    tt = {10,11,13}
    for elem in next(tt) do
        print(elem)
    end

    尾调用

    当一个函数调用另一个函数的最后一个动作时,该调用就算是一条尾调用。

    尾调用不耗费任何栈空间,故在递归函数里使用尤现优势。

    function f(x) return g(x) end  -- 尾调用
    
    -- 任何数字作为参数都不会造成栈溢出
    function goo(n)
        if n > 0 then return goo(n-1) end
    end
    
    -- 以下都是不尾调用,只有符合“return <func>(<args>)”才算尾调用
    function f(x) g(x) end
    
    return g(x) + 1
    return g(x) or x
    return (g(x))
    
    -- 这种复杂的算尾调用
    return x[i].foo(x[j]+ a*b, i+j)

    默认形参

    function func(x)
        x = x or 0  -- 但是要注意,如果参数用布尔值,不能这么用
    end
  • 相关阅读:
    FFT入门
    FJOI省队集训 chessboard
    FJOI省队集训 florida
    树上莫队
    NOIP2015 Revenge
    APIO2013 tasksauthor
    油漆门
    一些字符串有关的题目
    字符串题模板集合
    sg函数与博弈论2
  • 原文地址:https://www.cnblogs.com/lsgxeva/p/7744823.html
Copyright © 2011-2022 走看看