表构造器

lua-users home
wiki


[!] 版本说明:此页面似乎有些过时,涉及到 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-enums)

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 (差异)