[Lua]: 值为1的键与普通的1不同

我一直在为我正在制作的游戏mod编写代码,但当输入键时遇到了表不返回值的问题:

for k, v in pairs(self.math) do
    print(self.exce[1])
    print(self.exce[k])
    print(k)
    if self.exce[k] ~= nil then
        self.math[k] = nil
    end
end

这是脚本中出现问题的具体部分。当我在游戏中运行这些代码时,它返回:

[lua]: true
[lua]: nil
[lua]: 1

这基本上意味着1不等于1。 我用来存储我的数据的函数是

function filterExceptions.server_onException( self, id )
    if self.exce[id] == nil then
        self.exce[id] = true
        self.network:sendToClients( "client_onList", id )
    else
        self.exce[id] = true
        self.network:sendToClients( "client_offList", id )
    end
end

在这个代码中,self是游戏创建的一个表,可以从中获取游戏数据或将数据存储在其中,而id来自我编写的一个函数以获取玩家的id。在这种情况下,该id为1(我多次打印了它)。我知道这段代码的每个部分都在工作,除了第一段中的代码,特别是尝试执行self.exce[k]的那部分。我尝试了很多,比如浏览self.exce中的每个变量,看看它是否在其中,然后做一些处理,但它仍然无法工作。Lua 让人很烦恼,它认为k~=1,而它绝对是1,在一个有效的部分中,我甚至使用了类似的代码。

那么这段代码有什么问题,它为什么不打印self.exce[k],而self.exce[1]却可以?不用担心表的创建和其他的东西,因为只要需要,在表不存在时会自动创建,否则就会报错。

点赞
用户9984411
用户9984411
似乎将 id 转换为字符串可以解决这个问题,但我还是不明白为什么这段代码在另一个模块上能运行,在这个模块上却不能。

function filterExceptions.server_onException( self, id ) local id2 = tostring(id) if self.exce[id2] == nil then self.exce[id2] = true self.network:sendToClients( "client_onList", id ) else self.exce[id2] = true self.network:sendToClients( "client_offList", id ) end end

```

2018-06-24 09:01:56
用户10018042
用户10018042

综合一些评论和你的代码,看起来在“for in pairs”循环的某个特定迭代中(或者可能是所有迭代,但稍后会谈到这一点),数组的索引值是一个字符串,而不是整数。

总结一下,如果你不想读整篇文章,“for k,v in pairs”循环将遍历整个数组,将“k”设置为值“v”的索引。似乎你的“for in pairs”循环正试图遍历空值,“k”为字符串而不是整数的情况。你可能还想使用“ipairs”而不是“pairs”在你的for循环中。

“someArray [1]”的值与“someArray [“ 1”]”的值不同。对于任何给定数组,“[1]”索引是完全不同的索引,与索引“[“1”]”不同。一个简单的修复方法是使用

ind = tonumber(k)
print(self.exce[ind])

这将把字符串“k”转换为数字类型。请注意,如果“k”是非数字字符串,这可能会引发错误。如果数组有任何值的索引为非数字字符串,则可能会出现错误。正如其他答案所指出的那样,将索引“k”转换为字符串而不是整数也可以起作用,并且如果你用非数字值作为你的索引,它不会抛出错误。

我猜这是为什么会发生的原因是,用于将数据存储到数组中的函数“filterExceptions.server_onException(self,id)”传递了一个字符串而不是整数,这将导致特定迭代中的k值被设置为一个字符串的“for in pairs”循环。

为了更好地理解这一点,这里有一个示例代码:

a = {true, false, false}
a[1] = true
a["1"] = true

print("Raw for in pairs loop")
for k, v in pairs (a) do
  print(type(k)..k)
end

print("For in pairs converting k to a number")
for k, v in pairs (a) do
  ind = tonumber(k)
  print(type(ind)..ind)
end

print("For in ipairs")
--which I'm not sure I completely understand but
--it seems to skip over any iteration where k is not a number
for k, v in ipairs(a) do
  print(type(k)..k)
end

这段代码会产生以下输出:

Raw for in pairs loop
number1
number2
number3
string1
For in pairs converting k to a number
number1
number2
number3
number1
For in ipairs
number1
number2
number3

编辑:我不确定“self.math”表中发生了什么,所以不能发表评论。

编辑2:我还要给你参考以下链接:lua:iterate through all pairs in table。那里的顶部答案应该有助于理解pairs和ipairs之间的区别,如果你还没有理解。你可以使用ipairs来防止使用pairs遍历v == nil的值。pairs将遍历每个键/值对,而ipairs将遍历从1开始的整数键,直到它遇到一个nil值。

编辑3:抱歉这个答案这么长...我只是想仔细一点。

2018-07-01 16:37:22