我读过Lua,它几乎是完美的语言,但是存在严重的错误。它是基于单一的索引。我还读到它有一个在索引0处设置值的功能,但它没有计算表长度,字符串操作仍然是基于一个。所以这个功能毫无意义。
我不想煽动基于一个或基于零。我只想问是否有强制使用从零开始的索引的功能。
我读过Lua,它几乎是完美的语言,但是存在严重的错误。它是基于单一的索引。我还读到它有一个在索引0处设置值的功能,但它没有计算表长度,字符串操作仍然是基于一个。所以这个功能毫无意义。
我不想煽动基于一个或基于零。我只想问是否有强制使用从零开始的索引的功能。
我认为Lua已经拥有了你需要让它基于0的功能。不幸的是,我所指的功能是Lua的开源许可证。
我无法找到Lua的补丁或分支,它改变了该语言的基于1的性质。
不幸的是,要求Lua将其更改为0也会破坏向后兼容性。所有当前附加模块的丢失可能是为了易于使用而付出的代价。
我知道这个问题已经有1年了,但我认为未来的搜索者会对这个事实感兴趣,CFF Explorer包含一个脚本语言(带补丁的Lua),它有0索引表补丁:
http://www.ntcore.com/files/cffscriptv2.htm
此外,在上面的文档中,作者声称他必须禁用大多数标准库函数,因为它们与0索引数组不兼容,所以请重申你对这个问题的思考过程:)
使用0索引数组实际上非常简单:
local array={
[0]="zero",
"one",
"two"
}
for i=0,#array do
print(array[i])
end
您可以使用 #array
不减去1,因为长度运算符实际上返回最高索引(技术上,第一个零之前的键),而不是实际的“长度”(无论如何在Lua中都没有意义)。
对于字符串运算符,您可能只需要创建重复的函数(尽管可能有更好的方法)
ipairs()
也只支持1索引,所以你必须定义自己的函数或只使用常规 for
代替。
即使有一个 #define TABLE_START_INDEX 1
在Lua的消息来源(我不相信它)你会通过改变它来拍摄你自己的腿。这是因为大多数库使用基于1的索引。因此,执行类似以下操作的任何代码都会破坏。
对于i = 1,#t do ...结束
您当然可以使用迭代器甚至创建辅助函数来避免这种情况。
function get_first(t)return t [1] end
可能虽然您尝试解决的实际问题比从0更改为基于1的索引更难。
Eonil对ponzao答案的评论: 真正的问题是基本语言应该是基于0的索引语言的C语言。必须正确转换脚本和主机之间的索引数据交换。
如果要将C数据结构公开给Lua,请使用 userdata
打包他们。您可以根据自己的喜好使用metatable来使索引行为。这样,您就可以确保正确的翻译。
肮脏的方法有一些缺点:
function zeroIndexed(tbl)
local mt = {}
mt.data = tbl
mt.__index = function(t, k)
return mt.data[(type(k) == "number" and k + 1 or k)]
end
mt.__newindex = function(t, k, v)
mt.data[(type(k) == "number" and k + 1 or k)] = v
end
mt.__len = function()
return #mt.data
end
return setmetatable({}, mt)
end
t = zeroIndexed({5, 6, 7})
print(t[0], t[1], t[2])
t[0] = 4
print(t[0], #t)
t[#t] = 8
print(t[#t - 1], #t)
Lua 5.2输出:
5 6 7
4 3
8 4
在Lua 5.1 #t
回报 0
因为 __len metamethod
表和字符串不受尊重。
但请记住 table.insert
和其他表格方法不再适用于此,因为插入现在通过 t[#t] = x
。
我不建议使用它。
您可以通过使用知道不同索引库的迭代器来修复此lua-flaw:
function iarray(a)
local n = 0
local s = #a
if a[0] ~= nil then
n = -1
end
return function()
n = n + 1
if n <= s then return n,a[n] end
end
end
但是,您仍然需要手动添加第0个元素:
用法示例:
myArray = {1,2,3,4,5}
myArray[0] = 0
for _,e in iarray(myArray) do
-- do something with element e
end