繁体   English   中英

带有嵌套表的Lua类实例

[英]Lua class instance with nested tables

简单的Lua游戏和简单的类是这样的:

creature = class({ 
name = "MONSTER BADDY!",

stats = { power = 10, agility = 10, endurance = 10, filters = {} },

other_things = ...
})

creatureA = creature.new()

creatureB = creature.new()

creatureA.name = "Frank"

creatureB.name = "Zappa"

creatureA.stats.agility = 20

creatureB.stats.power = 12

- 等等等等等等

非表值是每个实例各自的,但是表值在所有实例之间共享,并且如果我在一个实例中修改stats.X值,则所有其他实例将看到相同的stats表。

Q1:我的OO实施是否有缺陷? 我尝试使用LOOP并发生了相同的结果,我的逻辑是否存在根本缺陷?

问题2:您如何使每个生物实例都有自己的统计表(和子表)?

PS。 我无法平铺我的类表,因为它比示例复杂一点,并且使用此嵌套表实现简化了代码的其他部分。

之所以这样工作,是因为类实例在其元表中将类表设置为__index (很好,大多数实现都是以这种方式工作的)。因此,如果您访问creatureA.stats (并且无法在creatureA上找到stats ,则属于__index ),返回creature.stats 。状态 也许您应该阅读Lua 5.1参考手册:元表

您将无法在类的表构造函数中声明每个实例的变量(除非您将所有内容从类表深深复制到实例,否则将非常昂贵)

您必须在您的类实现使用的任何初始化函数中执行此操作:

creature = class
{
     __init = function(self, ...)
         self.stats = {power = 10, agility = 10, endurance = 10, filters = {}}
     end,
}

class不是Lua中的标准函数。 您不会说是从罗伯托(Roberto)借来的,还是自己动手制作的,等等。 但是我的猜测是,您想更改new方法,以便它对原型进行深层复制 ,而不是浅层复制:

function deep_copy(v)
  if type(v) == 'table' then
    local u = { }
    for k, v in pairs(v) do
      u[k] = v
    end
    setmetatable(u, getmetatable(v))
    return u
  else
    return v
  end
end

(警告:我没有尝试编译此代码,更不用说运行它了。)

创建新creature ,如果您不希望共享它,则总是可以为其创建新的stats

creature = class({ 
    name = "MONSTER BADDY!",
    stats = stats.new({ power = 10, agility = 10, endurance = 10, filters = {} }),
    other_things = ...
})

力量,敏捷性等将作为stats的构造函数中的参数传递。

您称为班级的功能看起来可疑。 我会去寻找最简单的代码。 这是一个怪物类文件。 没什么好想的,有人会说它缺乏绒毛,但至少我下周也可以自己阅读代码。

-- Class object

monster = {}
monster.__index = monster

-- Class methods

function monster.new(name)
    local o = {}
    o.name = name
    o.stats = {power = 10, agility = 10, endurance = 10, filters = {}}
    setmetatable(o, monster)
    return o
end

function monster:shout()
    print('Aaaaaaa! My name is ' .. self.name .. '!')
end

这是输出:

> lua
Lua 5.1.4  Copyright (C) 1994-2008 Lua.org, PUC-Rio
> require 'monster'
> m = monster.new('Katla')
> m:shout()
Aaaaaaa! My name is Katla!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM