为什么这可以与点运算符一起使用?

时间:2018-12-25 13:22:08

标签: lua

我目前正在关注http://howtomakeanrpg.com/a/classes-in-lua.html上有关类的教程,并试图找到使用冒号运算符的逻辑。据我了解,冒号运算符在函数定义之外所做的唯一一件事就是将其前面的表作为不可见的参数传入。

下面,我以不同的方式创建了三个怪物,以试图弄清楚这一点。我完全不明白这一点,因为当呼叫第二个怪物时,不需要我将表传递给怪物?为什么我要把表Monster_3(我测试过是表类型)作为参数,而不是表:Monster是传入的表?还是只是说Create在表Monster内部的点。这对我完全没有意义。

我还认为新对象已添加到父表中,但是当我检查表中的monster_(number)是否存在时:Monster我得到了零。什么???然后这些新的monster_1,2,3表存储在哪里?

感谢您的光临,

Xpali

   Monster = {}
function Monster:Create()
    local this =
    {
        name = "orc",
        health = 10,
        attack = 3
    }

    function this:WarCry()
        print(self.name .. ": GRAAAHH!!!")
    end

    return this

end

monster_1 = Monster:Create()
monster_2 = Monster.Create()
monster_3 = Monster.Create(monster_3)

print(monster_1.name) -- orc
print(type(monster_1)) -- table
print(type(Monster.monster_1)) -- nil

print(monster_2.name) -- orc
print(type(monster_2)) -- table
print(type(Monster.monster_2)) -- nil

print(monster_3.name) -- orc
print(type(monster_3)) -- table 
print(type(Monster.monster_3)) -- nil

monster_1:WarCry() -- orc: GRAAAHH!!!
monster_2:WarCry() -- orc: GRAAAHH!!!
    monster_3.WarCry(monster_3) -- orc: GRAAAHH!!!    

1 个答案:

答案 0 :(得分:0)

上面的代码对于类实例化不是很容易表达,因为使用的构造函数没有参数。结果,所有3个实例都是相同的。另外,“ Monster.monster_1”和类似的不是NOT实例,它们是nil。

要查看更有趣的内容,我准备了以下代码示例:

-- Default properties values
local Monster = {
  name = "orc",
  health = 10,
  attack = 3
}

-- constructor
function Monster:Create(instance_name)
  -- take defaults from self (that is Monster table)
  instance_name = instance_name or self.name
  return {
    name = instance_name,
    health = self.health,
    attack = self.attack,
    WarCry = function(this)
      print(this.name .. ": GRAAAHH!!!")
    end
  }
end

monster_1 = Monster:Create()
monster_2 = Monster:Create("named") 
--monster_2 = Monster.Create() -- Incorrect use!
--monster_3 = Monster.Create(monster_3) -- Incorrect use!

print(monster_1.name) -- orc
print(type(monster_1)) -- table

print(monster_2.name) -- named
print(type(monster_2)) -- table

monster_1:WarCry() -- orc: GRAAAHH!!!
monster_2:WarCry() -- named: GRAAAHH!!!

现在,构造函数具有一个显式参数(“ instance_name”)和一个隐式参数(Monster表)。最后一个是使用“ self”关键字所必需的。因此,我们不应在实例化时使用点语法,否则会导致错误。如果在构造函数定义中避免使用“ self”,则可以使用点语法而不会出现错误,如下所示:

-- constructor
function Monster:Create(instance_name)
  -- take defaults from self (that is Monster table)
  instance_name = instance_name or Monster.name
  return {
    name = instance_name,
    health = Monster.health,
    attack = Monster.attack,
    WarCry = function(this)
      print(this.name .. ": GRAAAHH!!!")
    end
  }
end

monster_1 = Monster:Create()
monster_2 = Monster.Create(nil, "named") 

在上一次通话中注意“ nil”。该参数是必需的,因为构造函数是用冒号语法定义的,但是我们使用点调用。如果省略“ nil”参数,则“ named”值将被视为冒号上下文中的父表。

已添加:

我们还可以使用点语法创建构造函数:

Monster.CreateByDot = function(instance_name)
  instance_name = instance_name or 'Noname';
  return {
    name = instance_name,
    WarCry = function(this) 
      print(this.name .. ": GRAAAHH!!!")
    end
  } 
end

monster_3 = Monster.CreateByDot()
monster_4 = Monster.CreateByDot('Fourth')

monster_3:WarCry() -- Noname: GRAAAHH!!!
monster_4:WarCry() -- Fourth: GRAAAHH!!!

并查看实际使用的参数“ instance_name”。