計算 Lua 的 Table長度
在 Lua 中,我們可以通過這個符號”#“ 來計算字串的長度和一個table的長度,比如:
str = “I`am a string!”
print(#str) => 14
通常這個#符號也可以用來計算一個 Table 的長度,比如:
t = {1, 2, 3, 5, 100}
print(#t) => 5t = {1, 2, 3, 5, {}, 100}
print(#t) => 6
上面兩個例子都很好理解,再來看一個:
t = {1, 2, a=3, 5, {}, 100}
print(#t) => 5
這裡 a=3 不能算是sequence序列的一個成員,所以a=3並沒有被統計進去,再來看看這個列子:
t = {1, 2, a=3, nil, 100}
print(#t)
這個大家可以試試,我的lua版本是5.2 輸出結果是 4
t = {1, 2, a=3, nil}
print(#t) => 2
可以看到,當sequence中有nil的時候,這個結果就有點不好理解了,如果nil也被統計進長度,那麼上面的例子輸出應該是3而不是2,如果不統計那麼倒數第二個例子應該是輸出3而不是4,這是為什麼呢?
先來看看 Lua 5.1 對 這個#操作的定義,這個定義可以寫的不是很好理解,但是也能看出來#對lua table的單目操作是定義在這個table裡所有成員都是非nil的前提下,Lua 5.2的定義更容易讓人明白,引用:
A program can modify the behavior of the length operator for any value
but strings through the __len metamethod (see §2.4).Unless a __len metamethod is given, the length of a table t is only
defined if the table is a sequence, that is, the set of its positive
numeric keys is equal to {1..n} for some non-negative integer n. In
that case, n is its length. Note that a table like{10, 20, nil, 40} is not a sequence, because it has the key 4 but does not have the key 3. (So, there is no n such that the set {1..n}
is equal to the set of positive numeric keys of that table.) Note,
however, that non-numeric keys do not interfere with whether a table
is a sequence.
可以看到,類似{10, 20, nil, 40}這樣的table並不能定義為一個sequence,自然#符號對這個table的操作就是無效的,未有定義的,如果一定要計算這樣的table或者處理table中有a=2 這樣的非sequence元素的時候,則需要自己修改metatable來定義__len這個函式實現自定義的處理方法,這個下次再說。
因為這個原因業務上吃了大虧,記錄下修改程式碼去了