1. 程式人生 > >Lua小技巧

Lua小技巧

內容 變量 cto print 三個點 iter comment tor 來源

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

Lua小技巧