表構造函數

lua-users home
維基


[!] 版本資訊:此頁面似乎有點過時,與 Lua 4 表構造問題有關,這些問題現在已在 Lua 5 中解決,並且從分散的討論中並不能真正清楚地看出問題和解決方案是什麼。也許有人可以寫一篇關於此的摘要,並確定仍然存在的任何問題。--DavidManura

注意:哇,隨著 lua 4.1work4 的出現,這個提議已被採納(至少是最相關的部分)。

我甚至不知道 lua 作者注意到了我的提議,所以這讓我感到驚訝 - 我只能說:謝謝! :-)

還有一件事要做,我仍然認為這會很好:為範圍指定一個開始 t = {[97]="a","b","c","d","e"}

也許在某些情況下使逗號可選會很酷。(Joshua Jensen 在 2003 年 2 月再次提出了這個問題)


我認為目前在表構造函數中使用 ; 和 , 會造成混淆。至少這不是你可以通過閱讀示例代碼就能輕易推斷出來的東西。

如果有人看到兩個表 t = {1,2,3} 和 t2 = {x=1,y=2} 並嘗試直觀地組合它們,就會失敗。

我想知道是否可以改進表構造函數語法

目前,表構造函數分為兩部分:lfieldlist(類似向量的構造函數)和 ffieldlist(類似映射的構造函數),如果一個構造函數同時包含類似向量和類似映射的構造函數部分,則它們必須用分號分隔

t = {1,2;x=1,y=2}

我覺得這不直觀,我寧願這樣寫

t = {1,2,x=1,y=2}

或者更進一步,我希望能夠將兩者混合起來,像這樣

t = {1,2,x=1,y=2,3,4} -- equivalent to: {1,2,3,4;x=1,y=2}
t2 = {x=1,y=2;1,2,3,4;color="red"} -- equivalent to: {1,2,3,4;color="red",x=1,y=2}

還有一件很棒的事情是可以指定列表應該從哪裡開始:(有點像 c 語言中的枚舉)

t = {[97]="a","b","c","d","e"} -- equivalent to:
{[97]="a",[98]="b",[99]="c",[100]="d",[101]="e"}

為了實現這兩點,假設如果沒有給出明確的索引,則應使用最後一個數字索引 + 1。

注意:這必須是一個(對於大型列表來說很慢的)運行時計算。 [f()]="a" 是完全有效的,並且編譯器根本不知道 f() 將給出什麼索引。那麼你如何處理這個問題: { [1]=1, [3]=3, n=6, 11, 22 } 11 和 22 將獲得什麼索引?2 和 4?還是 2 和 3?還是 4 和 5?還是 7 和 8?那 n 呢?應該更新它嗎?這並不容易 ;-) --ET

{[1]=1, [3]=3, n=6, 11, 22} 應該等價於 {[1]=1, [3]=3, n=6, [4]=11, [5]=22} ,根據我的定義,使用最後一個(或更具體地說,最後使用的)數字索引 +1。我也想忽略掉混亂的“n”字段 ;)
為了更清楚地說明這一點,另一個例子: {[100]=0,[10]=1,2,3} 應該等價於 {[100]=0,[10]=1,[11]=2,[12]=3} - 不涉及複雜的運行時計算。只需在構造表時將最後使用的數字索引存儲在某個地方。--PeterPrade

為了向後兼容,";" 可以被視為等同於 ",", 因此所有這些形式都是有效的

t = {1,2,3}
t = {1;2;3}
t = {1,2;n=2}
t = {1,2,;n=2,}

為什麼要使用目前的語法?嗯,它可以幫助編譯器創建更高效的字節碼

v = {1,2,3}

產生以下優化代碼

     1  [1]     CREATETABLE     3
     2  [1]     PUSHINT         1
     3  [1]     PUSHINT         2
     4  [1]     PUSHINT         3
     5  [1]     SETLIST         0 3
     6  [1]     SETGLOBAL       0       ; v

m = {[1]=1, [2]=2, [3]=3}

產生效率較低的代碼

     7  [2]     CREATETABLE     3
     8  [2]     PUSHINT         1
     9  [2]     PUSHINT         1
    10  [2]     PUSHINT         2
    11  [2]     PUSHINT         2
    12  [2]     PUSHINT         3
    13  [2]     PUSHINT         3
    14  [2]     SETMAP          3
    15  [2]     SETGLOBAL       1       ; m

正如我們所看到的,如果我們使用 lfieldlist 來構造表,我們會得到更高效的代碼 - 即使生成的表完全相同。目前的表構造函數語法似乎是為了幫助解析器創建最高效的代碼,而無需分析正在構造的表的內容。


總結:我希望看到這些東西改變

實現這個目標會很困難嗎?我認為不會

使分隔符可選的想法是行不通的,如下例所示: t={print "text"}

(PeterPrade)

它在表構造函數的 ffieldpart ({ name=value name=value ... }) 中是多餘的。只有 [expr]=value 字段需要一個(前導)逗號,這樣 [] 才不會成為前一個表達式的一部分。但這無論如何都會產生語法錯誤 (name=val[foo]=val2))。 --ET


有什麼意見嗎?(例如:“不要只是說說而已,去寫代碼吧!”或者“我喜歡目前的語法”)

還有其他想法嗎?


近期變更 · 偏好設定
編輯 · 歷史
上次編輯時間:2007 年 7 月 7 日 下午 8:25 GMT (差異)