Lua中奇怪的表错误

发布于 2024-12-01 12:39:58 字数 387 浏览 1 评论 0原文

好的,下面的 Lua 代码遇到了一个奇怪的问题:

function quantizeNumber(i, step)
    local d = i / step
    d = round(d, 0)
    return d*step
end

bar = {1, 2, 3, 4, 5}

local objects = {}
local foo = #bar * 3
for i=1, #foo do
    objects[i] = bar[quantizeNumber(i, 3)]
end
print(#fontObjects)

运行此代码后,对象的长度应该为 15,对吧?但不,是 4。这是如何工作的?我错过了什么?

谢谢,埃利奥特·博纳维尔。

Okay, so I've got a strange problem with the following Lua code:

function quantizeNumber(i, step)
    local d = i / step
    d = round(d, 0)
    return d*step
end

bar = {1, 2, 3, 4, 5}

local objects = {}
local foo = #bar * 3
for i=1, #foo do
    objects[i] = bar[quantizeNumber(i, 3)]
end
print(#fontObjects)

After this code has been run, the length of objects should be 15, right? But no, it's 4. How is this working and what am I missing?

Thanks, Elliot Bonneville.

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

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

发布评论

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

评论(2

赢得她心 2024-12-08 12:39:58

是的,是 4。

来自 Lua 参考手册:

表t的长度被定义为任何整数索引n,使得t[n]不为nil且t[n+1]为nil;此外,如果 t[1] 为零,则 n 可以为零。对于具有从 1 到给定 n 的非零值的常规数组,其长度恰好是该 n,即其最后一个值的索引。如果数组有“洞”(即其他非 nil 值之间的 nil 值),则 #t 可以是直接位于 nil 值之前的任何索引(即,它可以将任何此类 nil 值视为结束值)数组)。

让我们修改代码来查看表中的内容:

local objects = {}
local foo = #bar * 3
for i=1, foo do
    objects[i] = bar[quantizeNumber(i, 3)]
    print("At " .. i .. " the value is " .. (objects[i] and objects[i] or "nil"))
end
print(objects)
print(#objects)

运行此代码时,您会看到 objects[4] 为 3,但 objects[5]nil< /代码>。输出如下:

$ lua quantize.lua 
At 1 the value is nil
At 2 the value is 3
At 3 the value is 3
At 4 the value is 3
At 5 the value is nil
At 6 the value is nil
At 7 the value is nil
At 8 the value is nil
At 9 the value is nil
At 10 the value is nil
At 11 the value is nil
At 12 the value is nil
At 13 the value is nil
At 14 the value is nil
At 15 the value is nil
table: 0x1001065f0
4

您确实填写了表中的 15 个位置。然而,根据参考手册的定义,表上的# 运算符并不关心这一点。它只是查找值不为零且其后续索引 nil 的索引。

在这种情况下,满足这个条件的索引是4。

这就是为什么答案是4。Lua就是这样。

nil 可以看作代表数组的结尾。这有点像在 C 中,字符数组中间的零字节实际上是字符串的结尾,而“字符串”只是它之前的那些字符。

如果您的目的是生成表 1,1,1,2,2,2,3,3,3,4,4,4,5,5,5 那么您将需要重写您的 quantize 函数如下:

function quantizeNumber(i, step)
    return math.ceil(i / step)
end

Yes it is 4.

From the Lua reference manual:

The length of a table t is defined to be any integer index n such that t[n] is not nil and t[n+1] is nil; moreover, if t[1] is nil, n can be zero. For a regular array, with non-nil values from 1 to a given n, its length is exactly that n, the index of its last value. If the array has "holes" (that is, nil values between other non-nil values), then #t can be any of the indices that directly precedes a nil value (that is, it may consider any such nil value as the end of the array).

Let's modify the code to see what is in the table:

local objects = {}
local foo = #bar * 3
for i=1, foo do
    objects[i] = bar[quantizeNumber(i, 3)]
    print("At " .. i .. " the value is " .. (objects[i] and objects[i] or "nil"))
end
print(objects)
print(#objects)

When you run this you see that objects[4] is 3 but objects[5] is nil. Here is the output:

$ lua quantize.lua 
At 1 the value is nil
At 2 the value is 3
At 3 the value is 3
At 4 the value is 3
At 5 the value is nil
At 6 the value is nil
At 7 the value is nil
At 8 the value is nil
At 9 the value is nil
At 10 the value is nil
At 11 the value is nil
At 12 the value is nil
At 13 the value is nil
At 14 the value is nil
At 15 the value is nil
table: 0x1001065f0
4

It is true that you filled in 15 slots of the table. However the # operator on tables, as defined by the reference manual, does not care about this. It simply looks for an index where the value is not nil, and whose following index is nil.

In this case, the index that satisfies this condition is 4.

That is why the answer is 4. It's just the way Lua is.

The nil can be seen as representing the end of an array. It's kind of like in C how a zero byte in the middle of a character array is actually the end of a string and the "string" is only those characters before it.

If your intent was to produce the table 1,1,1,2,2,2,3,3,3,4,4,4,5,5,5 then you will need to rewrite your quantize function as follows:

function quantizeNumber(i, step)
    return math.ceil(i / step)
end
香草可樂 2024-12-08 12:39:58

函数 quantizeNumber 是错误的。您正在寻找的函数是 math.fmod:

objects[i] = bar[math.fmod(i, 3)]

The function quantizeNumber is wrong. The function you're looking for is math.fmod:

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