Lua 在创建对象时出现"attempt to index a nil value error"错误

我正在将一些代码放入一个模块中,以便可以绘制和维护多个副本。我遇到了这个常见的错误,但我看不出原因。我基本上理解了它在说什么,但是由于我能够从创建的表中看到一些打印输出,所以我不明白调用该模块包含的函数为什么会抛出此错误。

我已经阅读了 SO 上的所有答案,但仍然不知所措。我尝试在不同的阶段打印输出以查看问题所在,每件事都像我创建了该模块的一个实例一样工作,但错误仍然存在。

下面的代码已清理掉不必要的东西。

local orbitalCircle = include('lib/orbital_circle')

function init()
  c1 = orbitalCircle.new(20, 42, 18, 1.7, 16, 62, 15, c1Sequence)
  <-- 在此处,来自模块的 init 函数的代码将被打印输出
  c1:doFunc(param)  <-- 这将调用错误

模块:

local Orbital_Circle = {}

-- 设置变量
一些变量在这里

function Orbital_Circle.new(x, y, diameter, scale_factor, number_of_notes, beats_per_second, frames_per_second, sequence_data)
    print("Orbital_Circle running")
end

function Orbital_Circle:doFunc(param)
    self.var = param  <-- 我在这里更新了一个本地变量
        print("self.var")  <-- 然后我打印更新后的数字以进行健全性检查
end

return Orbital_Circle

我希望这个模块的实例中的变量得到更新,并且函数的代码得到运行,但是... 不幸的是出现了错误。

谢谢。

点赞
用户2858170
用户2858170

你的代码完全混乱了。

<-- 会因为意外的符号造成错误。

 c1 = orbitalCircle.new(20, 42, 18, 1.7, 16, 62, 15, c1Sequence)

将因为 orbitalCircle.new 没有返回值而给你一个关于索引全局空值 c1 的错误。

你的初始化函数不完整,并且你没有调用它,所以即使你修复了以上错误,提供的代码也不会做任何事情。

所报告的错误不是由你在此提供的任何代码行引起的。

下面的代码精简了一些不必要的东西。

我怕你删掉的太多了。

错误消息告诉你,你正在索引局部变量 n,这是一个在 n 的作用域定义的空值。

例如,此代码:

local n
function test()
  local b = n.a
end
test()

将导致错误消息:

input:3: attempt to index a nil value (upvalue 'n')

ntest 的内部值,因为它是在函数体外定义的局部变量,但不是全局变量。

2019-04-14 22:09:35
用户1009432
用户1009432

我正在将一些代码放入一个模块中,这样我就可以绘制和维护多个副本。

我认为这里有一些关于 Lua 模块的工作原理的误解。这是一个容易犯的错误。

在 Lua 中,当你require一个模块时,每个后续的 require 都是指向同一个代码。所以(例如)这两个变量包含完全相同的代码:

local orbitalCircle1 = require('lib/orbital_circle')
local orbitalCircle2 = require('lib/orbital_circle')

这意味着你不能单独使用 Lua 模块来创建类似 OOP 对象的东西,就像你正在尝试做的那样。你的new函数必须返回一些可以像类的实例一样使用的东西,对于每次调用都是一个唯一的表:

local Orbital_Circle = {}

local shared_variable = 1

function Orbital_Circle.new(x, y)
  -- 创建一个唯一的表
  local obj = {}

  -- 用 self.xxx 从表或对象方法中访问这些
  obj.x = x or 0
  obj.y = y or 0
  obj.var = "initial value"

  -- 现在使用显式 'self' 参数定义函数…
  function obj.doFunc(self, param)
    self.var = self.var .. " " .. param
    shared_variable = shared_variable + 1
  end

  -- … 或使用语法 'self' 糖果, ':'
  function obj:printVars()
    print("self.var = " .. self.var)
    print("shared_variable = " .. shared_variable)
    print("self.x = " .. self.x)
  end

  return obj
end

return Orbital_Circle

你也可以将方法定义为在 new 函数外的 local function 中,并且有一个 self 参数以及一个条目列表,如下:

obj.anotherMethod = functionDeclaredAtTopOfFile

…如果你喜欢的话,可以使事情更整洁。

2019-04-14 22:53:18