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