简体   繁体   English

带有嵌套表的Lua类实例

[英]Lua class instance with nested tables

Simple Lua game with simple class like so: 简单的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

-- blah blah blah - 等等等等等等

Non table values are individual to each instance, but table values are shared among all instances and if I modify a stats.X value in one instance, all other instances see the same stats table. 非表值是每个实例各自的,但是表值在所有实例之间共享,并且如果我在一个实例中修改stats.X值,则所有其他实例将看到相同的stats表。

Q1: Is my OO implementation flawed? Q1:我的OO实施是否有缺陷? I tried LOOP and the same result occured, is there a fundamental flaw in my logic? 我尝试使用LOOP并发生了相同的结果,我的逻辑是否存在根本缺陷?

Q2: How would you have each instance of creature have it's own stats table (and sub tables)? 问题2:您如何使每个生物实例都有自己的统计表(和子表)?

PS. PS。 I cannot flatten my class table as it's a bit more complicated than the example and other parts of the code are simplified with this nested table implementation. 我无法平铺我的类表,因为它比示例复杂一点,并且使用此嵌套表实现简化了代码的其他部分。

It works like that because class instances have the class table set as __index in their metatable ( well, most implementations work that way ) So if you access creatureA.stats ( and it can't find stats on creatureA , thus falls to __index ) it returns creature.stats . 之所以这样工作,是因为类实例在其元表中将类表设置为__index (很好,大多数实现都是以这种方式工作的)。因此,如果您访问creatureA.stats (并且无法在creatureA上找到stats ,则属于__index ),返回creature.stats 。状态 Maybe you should read up on Lua 5.1 Reference Manual: Metatables 也许您应该阅读Lua 5.1参考手册:元表

You won't be able to declare per-instance variables in the class's table constructor ( unless you deep copy everything from the class table to the instance, which would be quite expensive ) 您将无法在类的表构造函数中声明每个实例的变量(除非您将所有内容从类表深深复制到实例,否则将非常昂贵)

You'll have to do it in whatever initializer function your class implementation uses: 您必须在您的类实现使用的任何初始化函数中执行此操作:

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

class is not a standard function in Lua. class不是Lua中的标准函数。 You don't say if you've borrowed it from Roberto, rolled your own, or what. 您不会说是从罗伯托(Roberto)借来的,还是自己动手制作的,等等。 But my guess is that you want to change the new method so that it does a deep copy of the prototype instead of a shallow copy: 但是我的猜测是,您想更改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

(Alert: I haven't tried to compile this code, let alone run it.) (警告:我没有尝试编译此代码,更不用说运行它了。)

When creating a new creature you could always create a new stats table for it if you don't want it to be shared. 创建新creature ,如果您不希望共享它,则总是可以为其创建新的stats

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

Power, agility etc. would be passed as arguments in the constructor for stats . 力量,敏捷性等将作为stats的构造函数中的参数传递。

That function of yours called class looks suspicious. 您称为班级的功能看起来可疑。 I go would for simplest possible code. 我会去寻找最简单的代码。 Here is a monster class file. 这是一个怪物类文件。 Nothing fancy and some people would say it lacks some fluff but at least I can read the code myself next week too. 没什么好想的,有人会说它缺乏绒毛,但至少我下周也可以自己阅读代码。

-- 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

And here is the output: 这是输出:

> 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