为什么Lua数组(表)从1开始而不是0?


125

我不了解Lua这部分决定背后的理由。为什么索引从1开始?我读过(和其他很多人一样)这篇伟大的论文。在我看来,这门语言很奇怪,学习和编程都很愉快。不要误会我的意思,Lua很棒,但是在某处必须有一个解释。我在网上发现的大多数内容只是说索引从1开始。

阅读其设计师对这一主题的看法将非常有趣。

请注意,我是Lua的“非常”初学者,希望我不要对表失去任何明显的东西。


23
默认范围也是全局的。Lua的两个最大的缺点。
Yann Ramin 2010年

37
我不会称1为起点。实际上,这更有意义-程序员受过良好的训练,可以从我们不喜欢的其他语言中以基于0的索引进行思考。我们还受过训练,认为5/2 =2。这并不正确。
BlueRaja-Danny Pflughoeft,2010年

54
@ BlueRaja-DannyPflughoeft:不。零索引更有意义-人类在从1开始计数方面受过良好的培训,以至于以0开头的语言最初令人困惑。但是,我很想在此向您推荐Edsger Dijkstra:cs.utexas.edu/users/EWD/ewd08xx/EWD831.PDF
orlp

11
@nightcracker:当你对表计的苹果,你算第一个为“一”,第二个为“二”等 无人计数第一个“零”,然后添加一个末; 毫无疑问,从零开始计数是违反直觉的。是的,我意识到这就是索引在内部工作的方式,但这就是为什么我们将其称为抽象。
BlueRaja-Danny Pflughoeft13年

9
我从不了解对基于0的索引的所有热爱。对于偏移量(从一开始要跳过多少个项目?)和子序列(0≤x <n)很好,但是对于基本事物看起来是错误的(第二个元素被称为一个?第十个元素对应于索引九?WAT?) 。甚至程序员在尝试查找编译器报告的行时也从1开始计数...
marcus

Answers:


143

Lua是Sol的后代,Sol是为石油工程师设计的语言,未经计算机编程的正式培训。没有经过计算培训的人们认为,从零开始计数是不可思议的。通过采用基于1的数组和字符串索引,Lua设计师避免混淆了其第一批客户和赞助商的期望。

尽管一开始我也觉得它们很奇怪,但是我学会了爱基于0的数组。但是我对Lua的基于1的数组很满意,尤其是通过使用Lua的通用for循环和ipairs运算符-我通常可以避免担心数组的索引方式。


7
这只是历史上的营销原因。没有合理的理由,尤其是在当前时间。而且似乎您甚至都在尝试避免基于1的索引而不是利用它:)
eonil 2010年

27
@Eonil实际上避免显式索引会减少索引错误。
Dan D.

8
@Eonil的历史原因通常是相关原因。您从某件事开始,然后再也无法更改它,因为它会破坏所有现有代码。对于0对1索引来说特别糟糕,因为它的中断方式非常微妙。
CodesInChaos 2011年

5
区别是从1到Length到从0到-1之间,但是在for循环中,< length它更方便使用,并且更容易在“基于Weirdo 0的语言”上阅读。我承认,当我看到一个从1开始迭代的循环时,我立即假定它从第二个元素开始:S
Felype,2015年

45

Lua对表的首次讨论中的编程中,他们提到:

由于您可以使用任何值对表进行索引,因此可以使用任何您喜欢的数字来开始数组的索引。但是,在Lua中习惯以1(而不是像C中那样从0)开始数组,并且有一些设施遵循此约定。

稍后,在有关数据结构的章节中,他们再次说了几乎相同的话:Lua的内置功能假定基于1的索引。

无论如何,有对夫妇的便利,使用基于1的索引。即,#(长度)操作:t[#t]访问表中的最后一个(数字)索引,并t[#t+1]访问1 过去的最后一个索引。对于尚未接触过基于0的索引的人来说,#t+1越过列表的末尾会更直观。还有Lua的for i = 1,#t构造,我相信它与上一点属于同一类别,即“索引长度1”比索引“ 0长度减去1”更明智。

但是,如果您无法打破基于0的索引的思维方式,那么Lua的基于1的索引肯定会更多地成为障碍。最终,作者想要一些对他们有用的东西。而且我承认我不知道他们最初的目标是什么,但是从那时起它可能已经改变了。


16

我的理解是,仅是因为作者认为这样做是一种好方法,所以在他们向公众推出该语言后,这一决定就变得相当重要了。(我怀疑如果他们今天改变它,那就得付出地狱的代价!)我再也没有看到任何特别的理由了。


6
可能的理由:C仅这样做是因为数组基本上只是一个指针和array[0] == array + 0;,而当数组实际上是一个哈希表时,基于1的计数更为自然。
Maygarden法官10年

19
Lua索引实际上是索引。在C语言中,当您说索引时,您真正的意思是偏移量。
亚历克斯

8

可能没有那么重要的一点,但是我还没有听说过:更好的对称性是,字符串中的第一个和最后一个字符分别位于1和-1,而不是0和-1。


8
虽然这是很好的,这是不是为从1开始的原因
LHF

3

Lua库更喜欢使用从1开始的索引。但是,您可以使用所需的任何索引。您可以使用0,可以使用1,可以使用-5。它甚至在他们的手册中,也可以在(https://www.lua.org/pil/11.1.html)上找到。

实际上,这里的一些很棒的事情是内部lua库会将将通过0的某些SOME视为1。使用配对时要谨慎。
这样:("abc"):sub(0,1) == "a" and ("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

有没有一种方法,使({'a', 'b'})[1]评估为'b''a'有关系吗?这似乎是内置的。
remram

1
({[0] = 'a', 'b'})[1]
user2262111

0

真正的原因是该语言是葡萄牙法律中定义的实现,而主要的开发中心位于巴西,因此他们倾向于避免使用零或空或什么都不作为索引或下标。但是,该语言确实允许在某些版本的表创建函数中使用除1以外的起始索引。


5
即使这是真的,也与Lua的设计完全无关。
2013年

-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]))

-11

对于每个人来说,如果

table = {}

此刻,table是空的。所以,当

table == {something}

该表包含一些内容,因此table如果您知道我的意思,它包含的内容就是索引1 。

我的意思是它的表[0]存在,并且它的表= {},它是空的,现在程序员不会调用空表,而是先设置空表,然后将其填充,然后再找不到空表每次您要调用它时,都可以轻松创建一个空表。

我的英语不会更好,那是我最好的语法。如果您不喜欢它,您可以自由地不停地阅读它,但是给尝试帮助的人提供-rep会使人们根本不想帮助,尤其是在语法方面。我是一个数字和变量的人,不是语法。抱歉。


4
我没有得到表的值为0的概念。表的长度可以为0。但这与第一个索引的选择无关。我不在乎较小的语法错误,但是我根本不理解您的回答的重点,这就是为什么我投票否决。
CodesInChaos 2011年

就是这样,一个表不能用0的索引或值保存,因为我们将它用作空表<,<当您拥有从1“ n”表示的某个东西时,所以当您什么都没有时,您的空从某种意义上讲,这会导致我们出现“选拔”,但“选拔”计数,这是一种实用的语言,您不必出门告诉朋友您知道我有0首该艺术家的歌曲,或者您有一些,或者别。点它的表= {}多数民众赞成在一个空表
Wesker

5
0仅将索引用作元素的数组仍然不为空。实际上lua支持这一点,它不是默认约定。
CodesInChaos 2011年

是的,在其他一些语言上,我也同意你的看法,但不支持lua,不存在lua索引0,所以我们可以想象它像一个空= 0,或者即使当你可以将索引强制为0时,我也可以这样描述它,它不能与表值一起工作#table不会读取0索引,所以我的回答仍然是,它基本上像常规事件那样进行,现在,如果他们打算这样做或不真正相关,则不会再次编写孔代码,并且我们对此无能为力://我仍然相信,在lua中,一个空表的索引为0
Wesker,
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.