LUA尝试索引全局零值

我已经阅读了其他同名答案,但没有结果。我的问题看起来很简单,但我无法找到处理的方法。几天前刚开始学习LUA。在这里,它打印"nam",因此存在冲突。但是,display.remove(apple)无法正常工作。而removeSelf()会出现错误,“尝试索引全局变量'apple'(值为nil)”。我唯一想发生的事情是在碰撞时使苹果消失。

function appleCollision(self, event)
  if event.phase == "began" then
    print("nam")
    --display.remove( apple )
    apple:removeSelf()
    apple = nil
  end
end

local apple = display.newImageRect( "apple.png", 65, 85 )
apple.x, apple.y = 460, -100
apple.rotation = 15
apple:addEventListener ( "collision", apple )
apple.collision = appleCollision
physics.addBody( apple, { density=1.0, friction=0.3, bounce=0.3 } )
点赞
用户4984564
用户4984564

我想这会是一个多部分的答案...

词法作用域

典型的例子:

do
  local foo = 20
  function bar() return foo end
end
print(tostring(foo)) -- 输出 "nil",foo 已经失效
print(bar()) -- 输出 20,bar 仍然知道 foo

在你的情况下则相反:

function bar() return foo end
-- 此时还没有作为 local 的 foo,因此 Lua 尝试访问全局变量 foo
do
  local foo = 20
  print(tostring(bar())) -- 输出 nil,因为 bar 不知道 foo
end -- 程序忘记了 local foo
foo = 30 -- 全局变量
local foo = 20
print(bar()) -- 输出 30,因为它不知道 local foo

你的问题

这基本上就是你例子中所发生的情况。你在函数声明之后声明了 player 变量,因此在函数声明时,没有局部变量 player 存在,因此它编译出的函数访问一个全局 player 变量。由于该全局变量不存在,它被视为空,当您尝试索引它时 Lua 发出警告。

解决方法

  • 或者移除 local,使 player 成为全局变量(容易实现,但全局变量是魔鬼,不应该轻易使用)
  • 或者仅在函数上方声明 local player,然后可以在更下面为其赋值。

请注意,该函数将保存变量,而不是其值。在下面的例子中说明了我所说的内容:

local foo = 20
function bar() return foo end
foo = 30
print(bar()) -- 输出 30,而不是 20

还有更多要考虑的问题,但这是解决您问题所需了解的全部内容。如果您想学习更多,请在 Google 中搜索 Lua 的词法作用域,您肯定会找到比我更好的解释。

2018-09-25 14:56:28