Lua 为什么这适用于点运算符?

Lua 为什么这适用于点运算符?,lua,Lua,我目前正在关注关于类的教程,并试图找到冒号运算符使用方式中的逻辑。据我所知,冒号运算符在函数定义之外所做的唯一事情就是将它前面的表作为一个不可见的参数传入 下面我以不同的方式创建了三个怪物,试图了解其中的逻辑。我一点也不明白这一点,显然是因为当呼叫第二个怪物时,它不需要我在表中传递给怪物???为什么我可以把monster_3表(我已经测试过它是table类型)作为参数,table:monster不是传入的表吗?或者仅仅是一个圆点,上面写着“创造是在桌子里面的怪物”。这对我来说毫无意义 我还以为新

我目前正在关注关于类的教程,并试图找到冒号运算符使用方式中的逻辑。据我所知,冒号运算符在函数定义之外所做的唯一事情就是将它前面的表作为一个不可见的参数传入

下面我以不同的方式创建了三个怪物,试图了解其中的逻辑。我一点也不明白这一点,显然是因为当呼叫第二个怪物时,它不需要我在表中传递给怪物???为什么我可以把monster_3表(我已经测试过它是table类型)作为参数,table:monster不是传入的表吗?或者仅仅是一个圆点,上面写着“创造是在桌子里面的怪物”。这对我来说毫无意义

我还以为新对象被添加到父表中,但当我检查怪物(数字)是否在表中时:怪物我得到nill。什么???那么这些新的monster_1,2,3表存储在哪里

谢谢你看

Xpali


上面的代码对于类实例不是很有表现力,因为使用的构造函数没有参数。因此,所有3个实例都是相同的。此外,“Monster.Monster_1”和类似的不是实例,而是零

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

-- 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 table)。最后一个是使用“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”参数,“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!!!

请看实际操作中的参数“实例名称”。

非常有趣,但这并不能回答我的问题。从Monster:Create创建的实例存储在哪里?如果我说Monster:Create()和Monster.Create(Monster)不一样吗?如果我将Monster表作为参数传入,Monster表实际会发生什么?实例存储在变量中:Monster_1=Monster:Create()。monster_1是一个变量,用于存储实例(表类型)。清楚吗?若您传递了一个参数,那个么您应该了解它是否会在构造函数中使用,以及如何在构造函数中使用。这取决于构造函数。如果我们的构造函数不使用这个参数,我们可以说Monster:Create()和Monster.Create(Monster)是相同的。所以Monster:Create()运行Create函数并将其存储在=符号前面的变量中,Monster:Create()和Monster.Create(Monster)是相同的,因为该函数不使用Monster表?你说这取决于构造函数,你能举个例子说明Monster:Create()与Monster.Create(Monster)不一样吗?我之所以感到困惑,是因为我认为当你使用冒号操作符时,操作符前面的表总是传递给它后面的函数。但从本教程的代码中,我无法在函数中找到Monster表的函数。我在文章中添加了带有一个参数的“点”类型构造函数。为什么要将Monster本身作为参数值传递?您希望通过此操作获得什么结果?我认为在这个阶段我们只能设置一些属性(比如instance_name)。
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!!!