我能强制Lua的表索引从零开始吗?
我遇到了 Lua 的一个问题。它使用基于 1 的索引。这种语言有一种特性可以在索引 0 处设置值,但该值不会被计入表格长度,并且字符串操作仍然基于 1。因此,我认为该特性与索引无关,而是一种特殊的功能。
我不想就基于 1 或基于 0 进行争论。我只是想问是否有一种强制使用基于 0 的索引的特性。
原文链接 https://stackoverflow.com/questions/3430583
我认为Lua已经有你需要使其为0操作的功能了。不幸的是,我所提到的功能是Lua的开源许可证。
我无法找到一个修补程序或分支来改变语言的基于1的特性。
不幸的是,分叉Lua以将其改为0操作也会破坏向后兼容性。失去所有当前的附加模块可能是为了易于使用而付出的过高代价。
我知道这个问题已经有一年了,但我认为未来的搜索者会对这个事实感兴趣,即CFF Explorer包含一个脚本语言(带有补丁的Lua),它具有0索引表补丁:
http://www.ntcore.com/files/cffscriptv2.htm
此外,在上述文档中,作者指出他不得不禁用大部分标准库函数,因为它们与0索引数组不兼容,请重新思考这个问题的解决思路 :)
Eonil 对 ponzao 的回答的评论:真正的问题是基础语言应该是 C,这是一种从0开始索引的语言。脚本和主机之间的索引数据必须正确翻译。
如果要将 C 数据结构暴露给 Lua,请使用 userdata
将它们封装起来。您可以使用元表使索引行为按您喜欢的方式进行。这样,您可以确保正确的翻译。
答案:不,没有办法强制 Lua 处理过程中的所有索引都为 0,因为就我所知,#table 从 1 开始,到 n 结束,没有索引 0 就几乎没有用处,但这取决于你想要做什么,你可以比较两个表,一个读取产品,另一个读取收入,如果产品增加,则有更多,如果产品= 1,则为 nil,因此您只需读取一个表,而不是两个表。希望我表述清楚了。
将表格以零为索引的脏方法:
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
来插入的。
我不建议使用这个方法。
使用0索引数组实际上非常简单:
local array={
[0]="zero",
"one",
"two"
}
for i=0,#array do
print(array[i])
end
您可以使用#array
而不必减1,因为长度运算符实际上返回最高索引(技术上是第一个nil键之前的键),而不是实际的“长度”(在Lua中也没有意义)。
对于字符串运算符,您可能必须只创建重复的函数(虽然可能有更好的方法)
ipairs()
也仅支持1索引,因此您必须定义自己的函数或只使用常规for
。
你可以通过使用一个能够识别不同索引基准的迭代器来修复这个 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
直接答案是: 修改Lua的源代码。将所有对Lua“table”的操作改为从0开始。
我正在进行这项工作,并与Lua标准库一起执行。有Windows二进制可用。
http://lua-users.org/wiki/CountingFromOne(底部有一些评论)
https://github.com/farteryhr/lua-base-0(查看修改了什么的提交历史记录)
大部分工作都是有关+1 -1的脏活,而且大部分都已经完成。
请编写一些测试用例(尽可能涵盖语言的许多细节)并报告错误。
(目前已知元表仍有问题,但我找不到时间调查它)
我发现当与下标从 0 开始的语言(例如 C)交互时,最简单的方法就是不使用下标 0。这浪费了内存,但修改 Lua 相当荒谬。
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?
- addEventListener 返回 nil Lua
- Lua中获取用户配置主目录的跨平台方法
- 如何编写 Lua 模式将字符串(嵌套数组)转换为真正的数组?
即使在 Lua 源码中存在
#define TABLE_START_INDEX 1
(我不认为有这个),你基本上会因为将其改变而自断一臂。这是因为大多数库使用以 1 为基础的索引。因此,任何像下面这样的代码都会出现问题。当然,你可以使用迭代器或者甚至创建帮助函数来避免这个问题。
然而,你试图解决的实际问题可能比从 0 到 1 的基础索引更难。