我能强制Lua的表索引从零开始吗?

我遇到了 Lua 的一个问题。它使用基于 1 的索引。这种语言有一种特性可以在索引 0 处设置值,但该值不会被计入表格长度,并且字符串操作仍然基于 1。因此,我认为该特性与索引无关,而是一种特殊的功能。

我不想就基于 1 或基于 0 进行争论。我只是想问是否有一种强制使用基于 0 的索引的特性。

原文链接 https://stackoverflow.com/questions/3430583

点赞
stackoverflow用户206020
stackoverflow用户206020

即使在 Lua 源码中存在 #define TABLE_START_INDEX 1 (我不认为有这个),你基本上会因为将其改变而自断一臂。这是因为大多数库使用以 1 为基础的索引。因此,任何像下面这样的代码都会出现问题。

for i = 1, #t do ... end

当然,你可以使用迭代器或者甚至创建帮助函数来避免这个问题。

function get_first(t) return t[1] end

然而,你试图解决的实际问题可能比从 0 到 1 的基础索引更难。

2010-08-07 14:13:52
stackoverflow用户173806
stackoverflow用户173806

我认为Lua已经有你需要使其为0操作的功能了。不幸的是,我所提到的功能是Lua的开源许可证。

我无法找到一个修补程序或分支来改变语言的基于1的特性。

不幸的是,分叉Lua以将其改为0操作也会破坏向后兼容性。失去所有当前的附加模块可能是为了易于使用而付出的过高代价。

2010-08-07 18:34:59
stackoverflow用户682458
stackoverflow用户682458

我知道这个问题已经有一年了,但我认为未来的搜索者会对这个事实感兴趣,即CFF Explorer包含一个脚本语言(带有补丁的Lua),它具有0索引表补丁:

http://www.ntcore.com/files/cffscriptv2.htm

此外,在上述文档中,作者指出他不得不禁用大部分标准库函数,因为它们与0索引数组不兼容,请重新思考这个问题的解决思路 :)

2011-09-15 18:13:26
stackoverflow用户222815
stackoverflow用户222815

Eonil 对 ponzao 的回答的评论:真正的问题是基础语言应该是 C,这是一种从0开始索引的语言。脚本和主机之间的索引数据必须正确翻译。

如果要将 C 数据结构暴露给 Lua,请使用 userdata 将它们封装起来。您可以使用元表使索引行为按您喜欢的方式进行。这样,您可以确保正确的翻译。

2011-11-22 11:55:23
stackoverflow用户837969
stackoverflow用户837969

答案:不,没有办法强制 Lua 处理过程中的所有索引都为 0,因为就我所知,#table 从 1 开始,到 n 结束,没有索引 0 就几乎没有用处,但这取决于你想要做什么,你可以比较两个表,一个读取产品,另一个读取收入,如果产品增加,则有更多,如果产品= 1,则为 nil,因此您只需读取一个表,而不是两个表。希望我表述清楚了。

2011-12-06 09:55:24
stackoverflow用户1295187
stackoverflow用户1295187
将表格以零为索引的脏方法:

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来插入的。

我不建议使用这个方法。

2013-02-06 14:38:34
stackoverflow用户6232794
stackoverflow用户6232794

使用0索引数组实际上非常简单:

local array={
[0]="zero",
    "one",
    "two"
}

for i=0,#array do
    print(array[i])
end

您可以使用#array而不必减1,因为长度运算符实际上返回最高索引(技术上是第一个nil键之前的键),而不是实际的“长度”(在Lua中也没有意义)。

对于字符串运算符,您可能必须只创建重复的函数(虽然可能有更好的方法)

ipairs()也仅支持1索引,因此您必须定义自己的函数或只使用常规for

2017-06-20 19:23:09
stackoverflow用户673496
stackoverflow用户673496

你可以通过使用一个能够识别不同索引基准的迭代器来修复这个 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
2017-11-05 15:12:09
stackoverflow用户11207906
stackoverflow用户11207906

直接答案是: 修改Lua的源代码。将所有对Lua“table”的操作改为从0开始。

我正在进行这项工作,并与Lua标准库一起执行。有Windows二进制可用。

http://lua-users.org/wiki/CountingFromOne(底部有一些评论)

https://github.com/farteryhr/lua-base-0(查看修改了什么的提交历史记录)

大部分工作都是有关+1 -1的脏活,而且大部分都已经完成。

请编写一些测试用例(尽可能涵盖语言的许多细节)并报告错误。

(目前已知元表仍有问题,但我找不到时间调查它)

2019-03-15 10:01:35
stackoverflow用户14862418
stackoverflow用户14862418

我发现当与下标从 0 开始的语言(例如 C)交互时,最简单的方法就是不使用下标 0。这浪费了内存,但修改 Lua 相当荒谬。

2020-12-21 01:26:37