Lua 表取長度

來源:互聯網
上載者:User

標籤:des   使用   for   ar   art   代碼   amp   size   

稀疏數組的長度返回的不對,不知道算不算是個 bug?(在 Lua5.2.2 中測試的)
如果一個表容量一半的元素,用 ‘#‘ 取長度取的不對。但是對於小於容量一半的情況,表現的是對的。
根據 Lua 的代碼實現,‘#’號取表長度時取得是表中第一個空元素前的那個位置。
原文是(luaH_getn 注釋) :
Try to find a boundary in table `t‘. A `boundary‘ is an integer index such that t[i] is non-nil and t[i+1] is nil (and 0 if t[1] is nil).

看下例子:

a = {}for i = 1, 2 do    a[i] = i*3enda[4] = 811

用 #a 取得的結果是 4,而根據上面的描述應該取回 2。

再如:

for i = 1, 4 do    a[i] = i*3enda[8] = 811

用 #a 取得的結果是 8,而根據上面的描述應該取回 4。
在老一點的版本裡可以用 table.maxn 取最大下標,新版本裡這個介面被廢除了。
簡單的分析下原因,當表中的元素很少而下標的跨度很大時,也就是對於很稀疏的數組,儲存的時候存在表的雜湊部分。但當數組不是那麼稀疏的時候,就存在了數組部分,就是按下標從 1 遞增而來。這也是對空間使用的一種最佳化。
看下取長度的實現(只截取對分析有用的部分)

unsigned int j = t->sizearray;if (j > 0 && ttisnil(&t->array[j - 1])) {  // some codes}/* else must find a boundary in hash part */else if (isdummy(t->node)) /* hash part is empty? */  return j; /* that is easy... *///some other codes

注意 if 裡後面的那個表最後的一個元素判空操作,此時對於上面的兩段代碼 a[4] 或 a[8],剛好它們位於數組的最後一個元素,所以不是空,if 裡面不執行。由於這裡的表沒有雜湊部分,所以,到 else if 裡直接返回表長,也就是上面看到的 4 或 8。

不過,實際中,對於稀疏數組不要用 ‘#‘ 取長度,因為這個操作沒有什麼意義。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.