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

我不明白为什么 Lua 中的索引从 1 开始。我读过(和其他许多人一样)这篇伟大的论文。对于一个非常愉快的学习和编程的语言,它似乎是一个奇怪的角落。别误会,Lua 非常棒,但一定有一个解释。我在网络上找到的大多数是说索引从 1 开始。至此为止。

阅读设计者关于这个问题的观点应该是非常有趣的。请注意,我在 Lua 中是“非常”初学者,希望我没有错过任何显而易见的关于表格的东西。

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

点赞
stackoverflow用户65845
stackoverflow用户65845

我的理解是,这样做只是因为作者们认为这是一个很好的做法,当他们将该语言推向公众后,这个决定就变得更加坚定了。(我怀疑如果他们今天改变这种做法,可能会付出惨痛的代价!)我从未见过任何特定的理由解释它。

2010-05-07 01:58:33
stackoverflow用户126042
stackoverflow用户126042

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为基础的索引肯定会更加阻碍。归根结底,作者想要的是对他们自己有效的东西;我承认我不知道他们的最初目标是什么,但这可能已经发生改变。

2010-05-07 02:15:32
stackoverflow用户41661
stackoverflow用户41661

Lua 是从 Sol 演变而来的,Sol 是一种面向石油工程师设计的语言,这些工程师并没有接受过正式的计算机编程培训。那些没有接受计算机培训的人们认为在零开始计数十分奇怪。通过采用基于1的数组和字符串索引,Lua 的设计者避免了其第一批客户和赞助商的期望不一致。

虽然一开始我也觉得这些用法很奇怪,但现在我已经爱上了基于0的数组。但是我通过使用 Lua 的通用 for 循环和 ipairs 操作符来处理基于1的数组,尤其是我通常不需要担心数组是如何索引的。

2010-05-07 02:42:34
stackoverflow用户516274
stackoverflow用户516274

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

2010-11-24 14:18:15
stackoverflow用户837969
stackoverflow用户837969

大家都能理解,如果这样

table = {}

那么 table 是空的。所以,当这样

table == {something}

说明表里有东西,那么它包含的东西就是 table 中的索引1,如果你知道我的意思的话。

我的意思是 table[0] 存在,且它的 table = {},这是空的,现在程序员不会调用一个空表,他们会先设置然后再填充它,每次想要调用它时找到一个空表是无用的,所以更简单的办法是创建一个空的表。

2011-12-06 09:12:30
stackoverflow用户1578766
stackoverflow用户1578766

或许这只是一个不太重要的点,但是我还没有听到有人提到过:一个字符串的第一个和最后一个字符的下标分别为1和-1,比起0和-1更具对称性。

2012-08-06 09:05:47
stackoverflow用户5420570
stackoverflow用户5420570

在你的示例中,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]))
2016-11-07 09:12:30
stackoverflow用户2262111
stackoverflow用户2262111

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" 将会是真的。

你可以以索引01或任何其他值开始一个数组:

-- creates an array with indices from -5 to 5
a = {}
for i=-5, 5 do
  a[i] = 0
end
2017-12-22 11:38:51
stackoverflow用户8294610
stackoverflow用户8294610

在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的索引,他们选择易于理解的方便和效率。

2021-02-03 10:59:11