我有一个关于 Lua 的问题。它使用基于1的索引。语言具有在索引0处设置值的功能,但该值不会被计算为表长度的一部分,并且字符串操作仍然是基于1的。因此,我认为这个功能是特殊的,而不是与索引有关。
我不想争论基于1或基于0的问题。我只是想知道是否有一种强制使用基于0的索引的方法。
我有一个关于 Lua 的问题。它使用基于1的索引。语言具有在索引0处设置值的功能,但该值不会被计算为表长度的一部分,并且字符串操作仍然是基于1的。因此,我认为这个功能是特殊的,而不是与索引有关。
我不想争论基于1或基于0的问题。我只是想知道是否有一种强制使用基于0的索引的方法。
local array={
[0]="zero",
"one",
"two"
}
for i=0,#array do
print(array[i])
end
你可以使用#array
而不需要减去1,因为长度操作符实际上返回的是最高索引(技术上来说,是第一个nil之前的键),而不是实际的“长度”(在Lua中也没有意义)。
对于字符串操作符,你可能只需要创建重复的函数(虽然可能有更好的方法)
ipairs()
也只支持1个索引,所以你将不得不定义自己的函数或者只是使用常规的for
语句。
我知道这个问题已经有1年的历史了,但我认为未来的寻求者会对这个事实感兴趣,即CFF Explorer包含一个脚本语言(Lua带有补丁),其中有0索引表修补程序:
此外,在上面的文档中,作者表示他不得不禁用大多数标准库函数,因为它们与从0开始索引的数组不兼容,请再阐述一下您对这个问题的思考过程 :)table
的操作改为基于0。对于ponzao的回答,Eonil提到:真正的问题在于基础语言应该是C语言,这是一种从0开始进行索引的语言。在脚本和宿主之间交换索引数据时,必须正确翻译。
如果你想将C语言数据结构暴露给Lua,可以使用userdata
将它们打包起来。你可以使用元表使索引行为按照自己的意愿进行。这样,就可以确保正确的翻译。
一种有缺陷的不良方法:
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)
5 6 7
4 3
8 4
#t
返回 0
,因为对于表和字符串,不尊重 __len元方法
。但要记住,table.insert
和其他表方法将不再起作用,因为插入现在是通过 t[#t] = x
完成的。我不建议使用这种方法。即使在Lua源代码中有#define TABLE_START_INDEX 1
(我不相信会有),如果你改变了这个值,你基本上会自己给自己惹麻烦。这是因为大多数库都使用基于1的索引。因此,任何执行以下操作的代码都将出现问题。
for i = 1, #t do ... end
当然,您可以使用迭代器甚至创建帮助函数来避免这种情况。
function get_first(t) return t[1] end
但是,您尝试解决的实际问题可能比从0到1的索引更难。
您可以通过使用一个能够识别不同索引基础的迭代器来修复这个 Lua 缺陷:
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
然而,您仍需手动添加第零个元素:
使用示例:
myArray = {1,2,3,4,5}
myArray[0] = 0
for _,e in iarray(myArray) do
-- do something with element e
end
我发现当与一个从0开始索引的语言(例如C)进行接口时,最好不要使用索引0。虽然这会浪费一些内存,但改变Lua的方式相当荒谬。
你的问题的答案是否定的,目前我所知道的是没有办法强制所有Lua处理的过程都使用索引0,因为#table从1到“n”,没有索引0就几乎没用了,但这取决于你想做什么,你可以比较两个表格,一个读取产品,一个读取收入,如果产品增加了,你就有更多了,如果产品等于1,那么你就没有了,所以你只需要读取一个表格,而不是两个,希望我表达清楚了。<,<