Lua中的数组(表)为什么从1开始而不是从0开始?
我不明白为什么 Lua 中的索引从 1 开始。我读过(和其他许多人一样)这篇伟大的论文。对于一个非常愉快的学习和编程的语言,它似乎是一个奇怪的角落。别误会,Lua 非常棒,但一定有一个解释。我在网络上找到的大多数是说索引从 1 开始。至此为止。
阅读设计者关于这个问题的观点应该是非常有趣的。请注意,我在 Lua 中是“非常”初学者,希望我没有错过任何显而易见的关于表格的东西。
原文链接 https://stackoverflow.com/questions/2785704
在 Programming in Lua 的关于表的第一个讨论中,他们提到:
因为可以用任何值索引表,所以可以使用任意数字来开始一个数组的索引。但是,在 Lua 中,传统做法是从1开始(不是从0开始,如在C中),并且一些工具也保持这个惯例。
后来,在数据结构的章节中,他们又几乎再次说了同样的话:Lua 的内置工具假定以 1 为基础进行索引。
无论如何,使用以 1 为基础的索引的确有几个方便之处。特别是 #
(长度)运算符:t[#t]
可以访问表的最后一个(数值)索引,而 t[#t + 1]
访问最后一个索引后面的 1。对于没有接触过以 0 为基础进行索引的人来说,#t + 1
在移动到列表的末尾时可能更直观。还有Lua的 for i = 1,#t
结构,我认为它与前一个点属于同一类别,即“从1到长度”比索引“从0到长度减1”更合理。
但是,如果您无法打破以 0 为基础进行索引的思维模式,那么 Lua 的以1为基础的索引肯定会更加阻碍。归根结底,作者想要的是对他们自己有效的东西;我承认我不知道他们的最初目标是什么,但这可能已经发生改变。
Lua 是从 Sol 演变而来的,Sol 是一种面向石油工程师设计的语言,这些工程师并没有接受过正式的计算机编程培训。那些没有接受计算机培训的人们认为在零开始计数十分奇怪。通过采用基于1的数组和字符串索引,Lua 的设计者避免了其第一批客户和赞助商的期望不一致。
虽然一开始我也觉得这些用法很奇怪,但现在我已经爱上了基于0的数组。但是我通过使用 Lua 的通用 for
循环和 ipairs
操作符来处理基于1的数组,尤其是我通常不需要担心数组是如何索引的。
真正的原因是该语言是葡萄牙法律定义的实现,主要开发中心位于巴西,他们倾向于避免使用零或空或什么都没有作为索引或下标。但是,在某些版本的表格创建函数中,语言确实允许使用起始索引而不是1。
大家都能理解,如果这样
table = {}
那么 table
是空的。所以,当这样
table == {something}
说明表里有东西,那么它包含的东西就是 table
中的索引1,如果你知道我的意思的话。
我的意思是 table[0]
存在,且它的 table = {}
,这是空的,现在程序员不会调用一个空表,他们会先设置然后再填充它,每次想要调用它时找到一个空表是无用的,所以更简单的办法是创建一个空的表。
或许这只是一个不太重要的点,但是我还没有听到有人提到过:一个字符串的第一个和最后一个字符的下标分别为1和-1,比起0和-1更具对称性。
在你的示例中,table[0]
将 始终 返回nil(null)
,_除非_ 你自己给它赋值,例如table[0] ='some value'
然后table[0]
将返回'some value'
,这是你分配的。
以下是一个示例:
tbl = {"some"}
print("tbl[0]=" .. tostring(tbl[0]))
print("tbl[1]=" .. tostring(tbl[1]))
nothing = {}
print("nothing[0]=" .. tostring(nothing[0]))
print("nothing[1]=" .. tostring(nothing[1]))
nothing[0] = "hey"
print("(after assign)\nnothing[0]=" .. tostring(nothing[0]))
Lua 库通常喜欢使用从 1 开始的索引。然而,你可以使用任何你想要的索引,包括 0、1 或者 -5。这甚至在它们的手册中有说明,手册链接为:(https://www.lua.org/pil/11.1.html)。
实际上,有些内部 Lua 库将某些传递的 0 视为 1。但使用 ipairs 时需要小心。
例如,("abc"):sub(0,1) == "a" and ("abc"):sub(1,1) == "a"
将会是真的。
你可以以索引0、1或任何其他值开始一个数组:
-- creates an array with indices from -5 to 5
a = {}
for i=-5, 5 do
a[i] = 0
end
在C和Lua中,数组索引的具体定义是不同的。
在C数组中,它指的是:数组地址的项地址偏移量。
在Lua数组中,它指的是:数组中第n个元素。
为什么大多数语言使用基于0的索引?因为带有“偏移定义”的编译器代码更加方便和有效。它们通常处理地址。
然后是 Lua。这是 lua 5.3.5 中使用C的表索引代码:
const TValue *luaH_getint (Table *t, lua_Integer key) {
if (l_castS2U(key) - 1 < t->sizearray)
return &t->array[key - 1];
else {
Node *n = hashint(t, key);
for (;;) {
if (ttisinteger(gkey(n)) && ivalue(gkey(n)) == key)
return gval(n);
else {
int nx = gnext(n);
if (nx == 0) break;
n += nx;
}
}
return luaO_nilobject;
}
}
我们应该关注代码 &t->array[key - 1]
,它有一个减法操作。与基于0的索引相比,它不太有效。
但是,基于1的索引更接近人类语言。我们更关注英语、汉语、日语和其他语言中的第n个元素。
因此,我猜测Lua设计者选择了基于1的索引,他们选择易于理解的方便和效率。
- 如何在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 模式将字符串(嵌套数组)转换为真正的数组?
我的理解是,这样做只是因为作者们认为这是一个很好的做法,当他们将该语言推向公众后,这个决定就变得更加坚定了。(我怀疑如果他们今天改变这种做法,可能会付出惨痛的代价!)我从未见过任何特定的理由解释它。