【问题标题】:table returning nil value when calling function调用函数时表返回 nil 值
【发布时间】:2020-07-10 17:30:57
【问题描述】:

我试图通过几个函数传递一个表并返回它,但它只能在一定程度上起作用。我几乎可以肯定它与范围界定有关,但我无法解决,因为我是 LUA 的新手。 我尝试将表放在第 1 行并将其设置为全局,但无济于事。 错误:包参数:预期的表,但得到了 nil。

function returnToTunnel(movementTable)
    for i = table.maxn(movementTable), 1, -1  do  --this is where I get the error.
        if (movementTable[i] == 1) then
            turtle.down()
        elseif (movementTable[i] == 2) then
            turtle.up()
        elseif (movementTable[i] == 3) then
            turtle.back()
            turtle.turnRight()
        elseif (movementTable[i] == 4) then
            turtle.back()
            turtle.turnLeft()
        elseif (movementTable[i] == 5) then
            turtle.back()
        end
    end
end

function mineOre(locationParam, movementTable)
    if (locationParam == 1) then
        turtle.digUp()
        turtle.suckUp()
        turtle.up()
        table.insert(movementTable, 1)
    elseif (locationParam == 2) then
        turtle.digDown()
        turtle.suckDown()
        turtle.down()
        table.insert(movementTable, 2)
    elseif (locationParam == 3) then
        turtle.turnLeft()
        turtle.dig()
        turtle.suck()
        turtle.forward()
        table.insert(movementTable, 3)
    elseif (locationParam == 4) then
        turtle.turnRight()
        turtle.dig()
        turtle.suck()
        turtle.forward()
        table.insert(movementTable, 4)
    elseif (locationParam == 5) then
        turtle.dig()
        turtle.suck()
        turtle.forward()
        table.insert(movementTable, 5)
    end
    locationParam = oreCheck()
    if (locationParam > 0) then
        mineOre(locationParam, movementTable)
    else
        return movementTable
    end
end

function digTunnel(tunnelLengthParam)
    local oreFound
    local movement = {}

    for i = 1, tunnelLengthParam do
        turtle.dig()
        turtle.forward()
        oreFound = oreCheck()
        if (oreFound > 0) then
            movement = mineOre(oreFound, movement)
            returnToTunnel(movement)
        end
        if ((i % 2) == 1) then
            turtle.digUp()
            turtle.up()
        elseif ((i % 2) == 0) then
            turtle.digDown()
            turtle.down()
        end
        oreFound = oreCheck()
        if (oreFound > 0) then
            movement = mineOre(oreFound, movement)
            returnToTunnel(movement)
        end
    end
end

所以,digTunnel 函数调用了另外两个函数 mineOre 和 returnToTunnel。

我一直在查看 LUA 手册和几个网站,但无法弄清楚。 感谢您的帮助!

【问题讨论】:

  • 只是一个提示:如果你想实现回溯,你可以很容易地使用递归:D
  • @DarkWiiPlayer 不幸的是我不知道怎么做。我选择了这张桌子,因为它记录了运动,我希望它在完成矿石开采后返回。我什至不知道如何通过递归来做到这一点,但我想这样做。 :)
  • 有一个功能:扫描矿石,挖掘它们,移动到那个地方,调用自己,然后返回到它的初始位置。每个函数只前后移动一个块,所以你总是在同一个位置结束:D

标签: function lua parameter-passing lua-table


【解决方案1】:

当 locationParam > 0 时,您的函数 mineOre 不返回表而是返回 nil。

if (locationParam > 0) then
  mineOre(locationParam, movementTable)
else
  return movementTable
end

因此这将导致一个 nil 值最终出现在 table.maxn

 movement = mineOre(oreFound, movement)
 returnToTunnel(movement)

【讨论】:

  • 我明白了。我要去的地方是,首先在挖掘隧道时它会扫描矿石。如果它找到一个,它将进入 mineOre 函数。由于矿石是分组的,我希望它是递归的。 if 条件就是这样做的,如果附近有任何矿石,则扫描矿石的函数会返回一个大于 0 的数字。基于此,它将再次开始挖矿。因此,如果我将代码更正为 return mineOre(locationParam, movementTable),它仍然会是递归的,并会为我提供一个包含多个条目的表格,对吗?
  • 是的,但您不必首先指定movement = mineOre,因为表格是通过引用复制的。无论如何,所有递归调用都将对相同的表值进行操作。
  • 很高兴知道,谢谢!该程序之后完美运行。
猜你喜欢
  • 2014-07-25
  • 2017-07-03
  • 2018-09-16
  • 2018-10-29
  • 2020-01-05
  • 1970-01-01
  • 2016-04-23
  • 1970-01-01
  • 2017-11-25
相关资源
最近更新 更多