表构造器 |
|
我甚至不知道 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"}
在表格构造器的 ffieldpart ({ name=value name=value ... })
中是多余的。只有 [expr]=value
字段需要一个(前导)逗号,这样 []
不会成为前一个表达式的部分。但这会导致语法错误(name=val[foo]=val2)
)。--ET
还有其他想法吗?