1. 程式人生 > >【小白學Lua】之Lua變長引數和unpack函式

【小白學Lua】之Lua變長引數和unpack函式

一、簡介

  Lua的變長引數和unpack函式在實際的開發中應用的還挺多的,比如在設計print函式的時候,需要支援對多個變數進行列印輸出,這時我們就需要用到Lua中的變長引數和unpack函數了。

二、Lua變長引數與unpack函式

  Lua中支援可變引數,用 ... 表示。比如定義下面的這樣一個函式:

local function func1(...)
end

  當然它也支援在變長引數前面新增固定引數:

local function func1(var,...)
    --dosomething
end

  我們在使用變長引數的時候,首先需要將其獲取,然後再使用,程式碼如下:

 local function func(...)
    local args = { ... } --這裡的...和{}符號中間需要有空格號,否則會出錯 
    print (#args)
 end
 
 func(1,2,"string",4,5)

  可以發現將變長引數用花括號進行打包以後,會得到一個table,之後就跟我們平時應用Lua沒什麼區別了。接著我們再來看看unpack函式,在Lua裡面我們通常使用它來將陣列形式的table拆開。這個函式有三個引數,第一個引數就是要拆的table,第二個引數是起始元素的下標,預設為1,第三個引數是結束元素的下標,預設為table的長度。函式原型如下:

  舉個栗子,看看如何使用,由於其特性,unpack還可以作為尾呼叫來提供多個返回值:

local info={1,2,3,4,5,6}
local a,b,c,d,e,f = unpack(info)
print(a,b,c,d,e,f)
--輸出結果:1   2   3   4   5   6

local function func1 (t)
    return unpack(t)
end
local v1,v2,v3,v4,v5,v6 = func1(info)
print(v1,v2,v3,v4,v5,v6)

  需要注意的一點是,如果遇到陣列下有nil,或者有字母key的時候,unpack將會返回nil,程式碼如下:

local info={1,2,3,nil,5,p=6}
local a,b,c,d,e,f=unpack(info)
print(a,b,c,d,e,f)
輸出結果:1   2   3   nil    5   nil

三、小例項---拓展print函式

  我們都知道在lua中可以用print函式進行列印操作,它本身也支援傳遞變長引數,不過美中不足的就是它不支援列印table中的內容,比如下面的這段程式碼:

print(1,2,3,{123,456})

  執行上面的這段程式碼,你通常會得到類似下面的這種輸出:

1       2       3       table: 00FE9950

  可以看到table中的元素沒有被一一打印出來,因此我們可以利用lua的變長引數的功能來對print進行拓展,使他支援列印table中元素的內容:

 1 local raw_print = print
 2 
 3 local function printTable(t)
 4     if type(t) == "table" then
 5         for _,v in pairs(t) do
 6             if type(v) == "table" then
 7                 printTable(v)
 8             else
 9                 raw_print(v)
10             end
11         end
12     end
13 end
14 
15 local function printExt(...)
16     local args = { ... }
17     for _,v in pairs(args) do
18         if type(v) == "table" then
19             printTable(v)
20         else
21             raw_print(v)
22         end
23     end
24 end
25 
26 rawset(_G,"print",printExt)
27 
28 print(1,2,3,{123,456,{"abc"},nil})

  簡單說一下原理吧,先用區域性變數將lua原始的print函式儲存下來備用。然後分別定義printTable和printExt函式。printTable使用遞迴的方式對錶中的元素進行遍歷及列印。printExt會遍歷外部傳進來的多引數,然後根據型別進行分別處理。最後將全域性環境中的原生print函式覆蓋為我們自定義的printExt。執行效果如下:

1
2
3
123
456
abc

四、總結

  在本篇部落格中,馬三同大家一起了解了Lua中變長引數和unpack函式的使用,並且通過拓展原生print函式的例項進行了練習。

 

 

如果覺得本篇部落格對您有幫助,可以掃碼小小地鼓勵下馬三,馬三會寫出更多的好文章,支援微信和支付寶喲!

       

 

作者:馬三小夥兒
出處:https://www.cnblogs.com/msxh/p/10054070.html  
請尊重別人的勞動成果,讓分享成為一種美德,歡迎轉載。另外,文章在表述和程式碼方面如有不妥之處,歡迎批評指正。留下你的腳印,歡迎評論!