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

发布于 2024-08-31 19:24:27 字数 306 浏览 1 评论 0原文

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

阅读其设计者对这个主题的看法将会非常有趣。

请注意,我是 Lua 的“非常”初学者,我希望我没有遗漏一些关于表的明显内容。

I don't understand the rationale behind the decision of this part of Lua. Why does indexing start at 1? I have read (as many others did) this great paper. It seems to me a strange corner of a language that is very pleasant to learn and program. Don't get me wrong, Lua is just great but there has to be an explanation somewhere. Most of what I found (on the web) is just saying the index starts at 1. Full stop.

It would be very interesting to read what its designers said about the subject.

Note that I am "very" beginner in Lua, I hope I am not missing something obvious about tables.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

香草可樂 2024-09-07 19:24:27

Lua 源自 Sol,这是一种为没有接受过计算机编程正规培训的石油工程师设计的语言。没有受过计算训练的人认为从零开始计数实在是太奇怪了。通过采用基于 1 的数组和字符串索引,Lua 设计者避免了混淆他们的第一批客户和赞助商的期望。

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

Lua is descended from Sol, a language designed for petroleum engineers with no formal training in computer programming. People not trained in computing think it is damned weird to start counting at zero. By adopting 1-based array and string indexing, the Lua designers avoided confounding the expectations of their first clients and sponsors.

Although I too found them weird at the beginning, I have learned to love 0-based arrays. But I get by OK with Lua's 1-based arrays, especially by
using Lua's generic for loop and the ipairs operator—I can usually avoid worrying about just how arrays are indexed.

灯下孤影 2024-09-07 19:24:27

Programming in 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 的索引肯定会成为一个障碍。最终,作者想要一些对他们有用的东西;我承认我不知道他们的最初目标是什么,但从那时起它可能已经改变了。

In Programming in Lua's first discussion of tables, they mention:

Since you can index a table with any value, you can start the indices of an array with any number that pleases you. However, it is customary in Lua to start arrays with 1 (and not with 0, as in C) and several facilities stick to this convention.

Later on, in the chapter on data structures, they say almost the same thing again: that Lua's built-in facilities assume 1-based indexing.

Anyway, there are a couple conveniences to using 1-based indexing. Namely, the # (length) operator: t[#t] access the last (numeric) index of the table, and t[#t+1] accesses 1 past the last index. To someone who hasn't already been exposed to 0-based indexing, #t+1 would be more intuitive to move past the end of a list. There's also Lua's for i = 1,#t construct, which I believe falls under the same category as the previous point that "1 to the length" can be more sensible than indexing "0 to the length minus 1".

But, if you can't break the mindset of 0-based indexing, then Lua's 1-based indexing can certainly be more of a hindrance. Ultimately, the authors wanted something that worked for them; and I'll admit I don't know what their original goal was, but it's probably changed since then.

踏月而来 2024-09-07 19:24:27

我的理解是,之所以这样做,只是因为作者认为这是一种好方法,而在他们向公众推出该语言后,这一决定变得相当僵化。 (我怀疑如果他们今天改变它,他们将付出惨重的代价!)除此之外,我从未见过任何特殊的理由。

My understanding is that it's that way just because the authors thought it would be a good way to do it, and after they rolled the language out to the public that decision calcified considerably. (I suspect there would be hell to pay were they to change it today!) I've never seen a particular justification beyond that.

终止放荡 2024-09-07 19:24:27

也许是一个不太重要的观点,但我还没有听说过:字符串中的第一个和最后一个字符分别为 1 和 -1,而不是 0 和 -1,这一事实具有更好的对称性。

Perhaps a less significant point, but one I haven't heard mentioned yet: there is better symmetry in the fact that the first and last characters in a string are at 1 and -1 respectively, instead of 0 and -1.

听,心雨的声音 2024-09-07 19:24:27

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

事实上,这里很酷的一点是内部 lua 库会将某些传递的 0 视为 1。使用 ipair 时请务必小心。
这样: ("abc"):sub(0,1) == "a" 和 ("abc"):sub(1,1) == "a" 将为 true。

 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

Lua libraries prefer to use indices which start at 1. However, you can use any index you want. You can use 0, you can use 1, you can use -5. It is even in their manual, which can be found at (https://www.lua.org/pil/11.1.html).

In fact, something cool here is internal lua libraries will treat SOME passed 0's as 1's. Just be cautious when using ipairs.
So that: ("abc"):sub(0,1) == "a" and ("abc"):sub(1,1) == "a" will be true.

 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
女皇必胜 2024-09-07 19:24:27

C 和 Lua 中数组索引的具体定义是不同的。

在C数组中,它的意思是:数组地址的项地址偏移

在Lua数组中,它的意思是:数组中的第n项

为什么大多数语言都使用从 0 开始的索引?因为带有偏移量定义的编译器代码更加方便有效。他们主要处理地址。

还有路亚。这是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的索引,他们选择简单易懂的纯粹更新的程序,放弃了便利性和有效性。

The specific definitions of array index in C and Lua, are different.

In C array, it means: item address offset of the array address.

In Lua array, it means: the n-th item in array.

Why most languages use 0-based index? Because the compiler code with offset definition is more convenient and effective. They mostly handle addresses.

And the Lua. This is the code of lua 5.3.5 for table index with 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;
  }
}

We should focus on the code &t->array[key - 1], it have a subtraction operation. It is not effective compared with 0-based index.

But, the 1-based index is more neared with human being languages. We focus more on n-th item in English, Chinese, Japanese and also.

So, I guess the Lua designers choose 1-based index, they choose easy understanding for pure newer of program, give up the convenience and effectiveness.

苏璃陌 2024-09-07 19:24:27

在您的示例中,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]))

In your example, table[0] will always return nil(null), unless you assign value to it yourself, like table[0] = 'some value' and then table[0] will return 'some value', which you assigned.

Here's an example:

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]))
划一舟意中人 2024-09-07 19:24:27

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

The real reason is that the language is an implementation of the definition in a law of Portugal and the major development centre was in Brazil and their preference is to avoid the use of zero or empty or nothing as an index or subscript. However the language does permit the use of a start index other than 1 in a table creating function in some versions.

挽梦忆笙歌 2024-09-07 19:24:27

这对每个人来说都是有意义的

table = {}

如果table 为空, 。因此,当

table == {something}

表包含某些内容时,它包含的就是 table 中的索引 1,如果您明白我的意思的话。

我的意思是 table[0] 存在,并且它的 table = {} 是空的,现在程序员不会调用空表,它会设置它们,然后填充它,每次要调用都找一个空表是没有用的,所以直接创建一个空表比较简单。

It makes sense to everyone, that if

table = {}

table is empty. So, when

table == {something}

The table contains something so what it contains is index 1 in table, if you know what I mean.

What I meant is that table[0] exists, and its table = {}, which is empty, now a programmer won't call a empty table, it sets them, and then fills it, it will be useless to find an empty table every time you want to call it, so it's simpler to just create an empty table.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文