lua - 在名为 foo.lua 的 Lua 文件中,名为 self.bar、foo.bar 和 bar 的变量之间有什么区别?

标签 lua coronasdk

与我的示例平行的是,我正在构建一个游戏并有一个名为 player.lua 的类。

几周前我编写了这个代码,当时我还不太了解 Lua 的工作原理,所以我没有为播放器构建的表格。

我已经为玩家分配了各种属性,例如 self.speed 或 self.strength。我希望(而且确实有效)这些属性都属于玩家。

我有一些问题,但我似乎找不到合乎逻辑、直观的答案。

如果我在 player.lua 中声明了一个表 (player = {}),那么 player.speed 将引用玩家表的“speed”键。但如果没有这样一张 table ,我目前实际上在做什么?

如果我在 player.lua 中使用 player.speed 而不是 self.speed 会怎么样?

如果将来我想在同一个游戏中同时拥有多个玩家怎么办?我如何像在 Java 中那样“实例化同一类的多个实例”,但在 Lua 中?这是否基本上涉及拥有一个中央游戏 lua 文件,比如 main.lua 或 game.lua,然后构建一个玩家表,其中每个元素本身就是一个玩家表?

比如说,listofPlayers = {} 你会去: table.insert(listOfPlayers, player:new()) where player:new() 会用玩家的所有默认属性实例化一个新表,然后返回该表?

那我什么时候使用元表呢?

最佳答案

元表

元表用于重载语言中的常见操作。这些操作可以包括加法、乘法、相等比较和(顾名思义)类似表的操作,例如通过键 table[key] 访问值。

元表通常用于在 Lua 中实现面向对象编程。驱动它的主要机制是使用 __index。这个例子将以最基本的形式说明这一点:

>>> parent = {parentID = 'Secret'}
>>> child = {}
>>> setmetatable(child,{__index=parent})
>>> =child.parentID
Secret

parentID 键实际上并不存在于 child 中,因此 child 中的无处有如下内容:

child = {
        parentID = 'Secret'
    }

相反,当有人查找 child 中不存在的 key 时,我们会去 parent 中查找,这是已设置的在我们分配给表的元表中:

>>> setmetatable(child,{__index=parent})

因此,当我们请求 child.parentID 时,以编程方式,事件流是:

  1. child 是否包含键为 "parentID" 的键值对?否,因此转到 2。
  2. child 是否在其元表中定义了 __index?是,转到 3。
  3. 查看 __index 引用的表以检查键 "parentID"
  4. 在父级找到!返回 parent["parentID"]
  5. 的值

所以这允许我们在表之间创建关系。我们可以使用 __index 元表方法在表示所有玩家信息的表与每个玩家自己之间建立关系,如下所示:

Player = { }
    Player_metatable = {
        __index = Player --look for the missing key in the Player table
    }

    function Player.new(name)
        aPlayer = { name = name } 
        setmetatable(aPlayer,Player_metatable)
        return aPlayer
    end 

    function Player:rotate()
        print("I'M ROTATING",tostring(self))
    end 

    henry =  Player.new("Henry")
    henry:rotate()

当我们调用 Player.new("Henry") 时,我们创建了一个表,并将其元表设置为 Player_metatable,就像设置 child 的元表一样 在第一个例子中。然而,我们只是在一个函数内执行它而不是直接执行,没有区别!

当我们调用 henry:rotate() 时,发生的情况如上文所述:我们在 henry 中寻找键 "rotate",但是找不到,所以我们在 Player 中查找(因为那是 __index 在我们的元表中指向的表)。我们有一个与该键关联的函数。因此,我们随后调用该函数,由于 t:function 语法,将我们自己传入。

要创建一个类的实例,您只需分配一个表,该元表指向您在其中定义类行为的表。所以我们可以创建任意数量的玩家:

my_player_name = Player.new(...)

修改 Player 表中的值,将反射(reflect)在具有关联元表的所有表中。

关于lua - 在名为 foo.lua 的 Lua 文件中,名为 self.bar、foo.bar 和 bar 的变量之间有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17258827/

相关文章:

coronasdk - Corona SDK : show emoji/images on native. showAlert()

audio - Corona SDK中的音频播放错误

image - 在 Corona sdk 中显示图像

ios - 停止功能 Corona SDK

ios - 如何在 iPhone 上使用 Corona sdk 旋转图像

c++ - Lua C 5.1 - 遍历所有全局值

c++ - 类似 Luabind 的语法(索引运算符)

LuaJIT 和 FFI : How to use char* properly?

ios - Swift:像 Lua 一样快速从数组中删除元素

c++ - 如何检查 SWIG 接口(interface)文件中的 Lua 版本?