为什么将参数传递给 lua 类方法会变为零

sdr*_*abb 1 lua parameter-passing

我有一种方法可以从 lua 中的父列表指针构建树。特别是我有这个lua 表

parents = {2,3,13,5,12,7,11,9,10,11,12,13,14,0}
Run Code Online (Sandbox Code Playgroud)

连同两个功能:

函数 1(创建节点):

function create_node(parent, i, created, root)
  if created[i] ~= nil then
        return
  end
    print(i)
--    print(parent)
--  Create a new node and set created[i]
    local new_node = Tree()
    new_node.idx = i
    created[i] = new_node


--    If 'i' is root, change root pointer and return
    if parent[i] == 0 then
       root[1] = created[i] -- root[1] denotes root of the tree

       return
    end

--    If parent is not created, then create parent first
    if created[parent[i]] == nil  then
        create_node(parent, parent[i], created, root )
    end
    print(i)

--    Find parent pointer
    local p = created[parent[i]]
    print (p)

    if #p.children <=2 then
      print(p.idx)
      print(created[i].idx)
      p.add_child(created[i])
    end

end
Run Code Online (Sandbox Code Playgroud)

函数 2(递归创建树): 我已经停止循环以测试从叶子到根的第一条路径,即 1-2-3-13-14

function read_postorder_parent_tree(parents)
    n = #parents

--    Create and array created[] to keep track 
--    of created nodes, initialize all entries as None
    created = {}

    root = {}
    for i=1, 1 do
        create_node(parents, i, created, root)
    end
    return root[1]
end
Run Code Online (Sandbox Code Playgroud)

create_note方法使用以下Tree类:

local Tree = torch.class('Tree')

function Tree:__init()
  self.parent = nil
  self.num_children = 0
  self.children = {}
end

function Tree:add_child(c)

  print(c)
  c.parent = self
  self.num_children = self.num_children + 1
  self.children[self.num_children] = c
end
Run Code Online (Sandbox Code Playgroud)

一切正常,但是当我调用p.add_child(created[i])参数时是nil为什么?(为什么cnil?)我已经检查了created[i]pnil。我该如何解决这个问题和/或为什么会发生这种情况?

这是我得到的错误:

parents = {2,3,13,5,12,7,11,9,10,11,12,13,14,0}
Run Code Online (Sandbox Code Playgroud)

Ill*_*ack 5

如果您以面向对象的方式定义一个函数,您也必须以相同的方式调用它。

function Tree:add_child(c)
Run Code Online (Sandbox Code Playgroud)

这使用冒号运算符以面向对象的方式声明了一个函数。为了帮助你理解这意味着什么,它可以这样重写:

Tree.add_child = function(self, c)
Run Code Online (Sandbox Code Playgroud)

如您所见,self创建了一个隐式参数来反映调用该函数的对象。但是,您可以通过标准方式调用该函数:

p.add_child(created[i])
Run Code Online (Sandbox Code Playgroud)

现在你可以看到你真正做的是通过created[i]as self,而不是 as c,然后当然碰巧为零。调用此类函数的标准方法也是通过冒号运算符:

p:add_child(created[i])
Run Code Online (Sandbox Code Playgroud)

这隐含传递pself实际功能,而现在p将包含实际参数。