我不明白Lua这一部分的决定背后的理由。为什么索引从1开始?我读过(和其他人一样)this great paper。在我看来,语言的一个奇怪的角落是非常愉快的学习和编程。不要误会我的意思,Lua很棒,但必须在某处做出解释。我发现的大部分内容(在网上)只是说索引从1开始。完全停止。
阅读其设计师对该主题的看法将非常有趣。
请注意,我是Lua的“非常”初学者,我希望我不会错过关于表格的明显内容。
答案 0 :(得分:125)
Lua是Sol的后裔,这是一种为石油工程师设计的语言,没有正式的计算机编程培训。没有接受过计算机培训的人认为从零开始计算是非常奇怪的。通过采用基于1的数组和字符串索引,Lua设计者避免混淆了他们的第一个客户和赞助商的期望。
虽然我在开始时发现它们很奇怪,但我学会了喜欢基于0的数组。但是我可以通过Lua的基于1的数组获得,尤其是
使用Lua的通用for
循环和ipairs
运算符 - 我通常可以避免担心数组的索引方式。
答案 1 :(得分:40)
在 Lua中的编程首次讨论表格时,他们提到:
由于您可以使用任何值索引表,因此您可以使用任何数字来启动数组的索引。但是,在Lua中习惯于使用1启动数组(而不是在C中启动数组),并且有几个设施坚持这个约定。
稍后,在关于数据结构的章节中,他们再次说了几乎相同的事情:Lua的内置工具假设基于1的索引。
无论如何,使用基于1的索引有一些几个便利。即,#
(长度)运算符:t[#t]
访问表的最后一个(数字)索引,t[#t+1]
访问1 过去最后一个索引。对于尚未接触过基于0的索引的人,#t+1
可以更直观地移动到列表的末尾。还有Lua的for i = 1,#t
构造,我认为它与前一点相同,“1到长度”比将“0到长度减去1”更为明智。
但是,如果你不能打破基于0的索引的思维模式,那么Lua基于1的索引肯定会成为一个障碍。最终,作者想要一些适用于他们的东西;而且我承认我不知道他们的原始目标是什么,但从那时起它可能已经改变了。
答案 2 :(得分:22)
有一个非常重要的理由不计算1中的数组:
如果数组从零开始,您可以以自然的方式将它们用作代数环。例如。我们有一周的日子(day={'mo', 'tu', 'we'...
),我们希望通过它们循环。那么写下心灵的意义要小得多:
nextday = day[(i+1)%7] as it is in almost every other language
比:
nextday = day[i%7+1] as it is in lua
起初似乎并不那么糟糕,但试着以另一种方式循环一周。
或者更一般地说:如果索引集缺少零,它缺少添加的中性元素。无论何时在索引计算中需要,都必须转移指数。
我是一名数学家,但我已经接受了这样一个事实,即在编程时,从零开始计算只是更好的选择..
答案 3 :(得分:14)
我的理解是,就是这样,因为作者认为这是一种很好的方式,并且在他们将语言推向公众之后,决定大大加重了。 (我怀疑如果他们今天改变它将会付出代价!)除此之外,我从未见过特别的理由。
答案 4 :(得分:5)
也许是一个不太重要的观点,但我还没有提到过:在字符串中的第一个和最后一个字符分别为1和-1而不是0和-1这一事实有更好的对称性。
答案 5 :(得分:1)
table [0]将总是返回nil(null),除非你自己为它赋值[0] ='某些值'然后表[0]将返回一些值'你指定的。
这是一个例子:
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]))
答案 6 :(得分:1)
Lua库更喜欢使用从1开始的索引。但是,您可以使用您想要的任何索引。你可以使用0,你可以使用1,你可以使用-5。它甚至在他们的手册中,可以在(https://www.lua.org/pil/11.1.html)找到。
事实上,这里很酷的东西是内部lua库会把Some传递给0作为1。使用ipairs时要小心谨慎 所以:(“abc”):sub(0,1)==“a”和(“abc”):sub(1,1)==“a”将为真。
You can start an array at index 0, 1, or any other value:
-- creates an array with indices from -5 to 5
a = {}
for i=-5, 5 do
a[i] = 0
end
答案 7 :(得分:0)
C 和 Lua 中数组索引的具体定义不同。
在C数组中,表示:数组地址的项地址偏移。
在 Lua 数组中,表示:数组中的第 n 项。
为什么大多数语言使用基于 0 的索引?因为带有offset definition
的编译器代码更方便有效。他们主要处理地址。
还有 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 的索引,他们选择易于理解的纯新程序,放弃了便利性和有效性。
答案 8 :(得分:-1)
真正的原因是该语言是葡萄牙法律中定义的实现,主要的发展中心是在巴西,他们倾向于避免使用零或空或无任何作为索引或下标。但是,该语言允许在某些版本的表创建函数中使用1以外的起始索引。
答案 9 :(得分:-1)
我最常用的表之一是 arg
表,起始索引是...
# /usr/local/bin/lua -i -e "for k,v in pairs(arg) do print(k..'='..v) end"
Lua 5.4.3 Copyright (C) 1994-2021 Lua.org, PUC-Rio
1=-i
2=-e
3=for k,v in pairs(arg) do print(k..'='..v) end
0=/usr/local/bin/lua
...零。
但是根据我如何调用 Lua(例如作为 shellscript 函数),它也可以是负数。
那么,这个shellscript函数...
lua ()
{
( /usr/local/bin/lua "${@}" -- .luarc )
}
...调用:lua -i
让我们看起来像这样...
0=.luarc
-3=/usr/local/bin/lua
-2=-i
-1=--
这是什么规则?
我决定让我每次检查 arg 中的序列。
答案 10 :(得分:-2)
它是在Sol之后制作的,Sol是一种由人们和没有任何编程经验的人制作的编程语言
示例强>
让我们假设您要将长度为3个字节的记录写入位置i
的数组
在基于0的语言上,这是找到开始写入记录的字节偏移量的公式:
var ptr = 3 * i
第一个元素(i = 0)给出偏移量0。 第二个元素(i = 1)给出偏移量3。 等等...
在基于1的语言中,首先尝试相同的方法:
var ptr = 3 * i
第一个位置(i = 1)给出3作为偏移但你应该得到1.所以你减去2以得到1.
var ptr = 3 * i - 2
到目前为止一切顺利。现在,您尝试使用i=2
公式。你得到4并且它是正确的。
通用公式为:
var ptr = L * (i-1) + 1
另一个例子
连接两个字符串时计算下一个偏移量也会导致复杂的公式:
以0为基础,你可以找到这样的偏移量:
var ptr = Len(string1) + Len(string2)
以1为基础的公式
var ptr = Len(string1) + Len(string2) + 1
我将矩阵乘法作为练习: - )
基本上使用基于1的表示法,您最终会在整个地方写入+1和-1,以便调整值。代码只是尖叫你使用基于0的索引方法
从数学的角度来看,在基于0或基于1的计算机上,索引基本上是从起点的偏移,不是> p>
答案 11 :(得分:-11)
每个人都有意义,如果是
table = {}
目前,table
为空。所以,什么时候
table == {something}
如果您知道我的意思,那么该表包含的内容就是table
中的索引1。
我的意思是它的表[0]存在,它的表= {},它是空的,现在程序员不会调用空表,它设置它们,然后填充它,它将是无用的每次要调用它时都会找到一个空表,因此只需创建一个空表就更简单了。
我的英语不会好起来,这是我最好的语法。 如果你不喜欢它,你可以自由地继续阅读它,但是给那些试图帮助的人提供-rep会让人们根本不想帮助,尤其是像语法这样的东西。 我是一个有数字和变量的人,而不是语法。遗憾。