1. ホーム
  2. lua

[解決済み] LUA がグローバルな nil 値のインデックスを作成しようとした

2022-02-10 21:53:54

質問

同じタイトルの他の回答も読みましたが、無駄でした。私の問題は簡単そうに見えますが、対処法がわかりません。数日前にLUAを始めたばかりです。ここでは、"nam"を出力しているので、衝突はしています。しかし、display.remove(apple)はうまくいきません。また、removeSelf()では、"attempt to index global 'apple' (a nil value)"というエラーが出ます。衝突時にappleに起こってほしいことは、appleが消えることだけです。

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 } )

解決方法は?

何回かに分けての回答になるかと思いますが...。

レキシカル・スコープ

典型的な例です。

do
  local foo = 20
  function bar() return foo end
end
print(tostring(foo)) -- prints "nil", foo is out of scope
print(bar()) -- prints 20, bar still knows about foo

あなたの場合は、その逆です。

function bar() return foo end
-- foo does not exist as a local yet, so Lua tries accessing a global foo
do
  local foo = 20
  print(tostring(bar())) -- prints nil because bar doesn't know foo
end -- forget about local foo
foo = 30 -- global
local foo = 20
print(bar()) -- prints 30, because it doesn't know the local foo

あなたの問題

あなたの例では、基本的にそのようなことが起こっています。あなたは player 変数が関数の後で宣言されているので、関数が宣言されるまでにローカル変数 player が存在しないため、グローバルな player という変数があります。このグローバル変数は存在しないので、nilとして扱われ、インデックスを作成しようとするとLuaは文句を言います。

修正

  • を削除するか local を作成し player をグローバル変数にする(簡単にできますが、グローバル変数は悪魔なので軽々しく使ってはいけません)。
  • だけで宣言することもできます。 local player を関数の上に置くと、さらにその下に値を割り当てることができます。

なお、この関数では 変数 のように、関数が作成されるときにその値ではなく。以下はその例です。

local foo = 20
function bar() return foo end
foo = 30
print(bar()) -- prints 30, not 20

これ以外にもいろいろありますが、問題を解決するために必要なことはこれくらいです。もっと詳しく知りたい場合は、「Lexical Scoping in lua」でググれば、きっと私よりも優れた解説が見つかるはずです。