2009-11-04 134 views
9

我無意中發現了一個怪異的行爲在Lua解壓功能Lua解壓縮錯誤?

table1 = {true, nil, true, false, nil, true, nil} 
table2 = {true, false, nil, false, nil, true, nil} 

a1,b1,c1,d1,e1,f1,g1 = unpack(table1) 
print ("table1:",a1,b1,c1,d1,e1,f1,g1) 

a2,b2,c2,d2,e2,f2,g2 = unpack(table2) 
print ("table2:",a2,b2,c2,d2,e2,f2,g2) 

輸出:

table1: true nil true false nil nil nil 
table2: true false nil nil nil nil nil 

第二解包提供參數到第一個零值。我可以忍受這一點。 第一張桌子提供4?參數中有一個是零。它有4個參數不是零,但它們不是顯示的參數。

任何人都可以解釋這一點嗎? 將其用codepad.org和LUA試圖5.1

回答

12

這個問題可以通過指定的開始和結束索引unpack(),並使用簡單解析作爲結束索引的table.maxn()

 
table1 = {true, nil, true, false, nil, true, nil} 

a1,b1,c1,d1,e1,f1,g1 = unpack(table1, 1, table.maxn(table1)) 
print ("table1:",a1,b1,c1,d1,e1,f1,g1) 
-->table1: true nil  true false nil  true nil 

處理兩個表時出現差異的真正原因在於確定表的數組部分長度的邏輯。

luaB_unpack()功能使用luaL_getn(),它是根據lua_objlen()定義的,它爲表格調用luaH_getn()luaH_getn()查看數組的最後一個位置,如果它是nil對錶中的邊界執行二分搜索(「使得t [i]非零且t [i + 1]爲零」)。數組末尾的二進制搜索是的處理方式與table2不同的原因。

如果數組中的最後一項是nil,這應該只是一個問題。零它裏面的元件 - - 長度操作者可以採用任何這些零元素作爲結束標記的當一個陣列具有孔

Programming in Lua(pg.16)(你應該買這本書。)。因此,應避免在可能包含孔的陣列上使用長度運算符。

unpack()正在使用長度運算符lua_objlen(),其中「可以假設任何[無]元素作爲數組的末尾」。

+0

謝謝,你救了我的一天。這是否意味着table.maxn()遍歷表的整個分配大小? – Geggamojja 2009-11-05 10:15:14

+0

table.maxn()「返回給定表的最大正數值索引」see http://www.lua.org/manual/5.1/manual.html#pdf-table.maxn – gwell 2009-11-05 16:41:23

+0

is table.maxn really really to在這裏返回正確的值(=表中的對象的數量)? – u0b34a0f6ae 2010-04-29 13:08:03

3

2.2 - Values and Types

[...] 類型實現關聯 陣列,即,陣列,可以是 索引不僅與數字,但 與任何值(除零)。表 可以是異構的;即他們 可以包含所有類型的值 (除外)。 [...]

鑑於nil到會突破表枚舉和你的變量不會被適當地初始化一個條目。

下面是一個簡單的例子,演示了一個問題行爲:

table1 = {true, false, nil, false, nil, true, nil} 
for k,v in ipairs(table1) do 
    print(k, v) 
end 

輸出:

1 true 
2 false 
>Exit code: 0 
+0

更具體地說,我懷疑它忽略了他指定的'nil'。 – RCIX 2009-11-04 11:03:51

+0

不,它不是RCIX,在這種情況下,表2會返回4個值,我猜也是如此。 – Geggamojja 2009-11-04 11:11:31

+0

for循環停止的唯一原因是迭代器在位置3處返回nil。由於assert(table1 [1] == true和table1 [2] == false以及table1 [3],表格仍舊正確初始化, == nil和table1 [4] == false和table1 [5] == nil和table1 [6] == true和table1 [7] == nil)'不會斷言。 – gwell 2009-11-04 23:27:29