この初版は Lua 5.0 向けに書かれています。その後のバージョンでも大部分は関連がありますが、いくつか違いがあります。
第 4 版は Lua 5.3 を対象にしており、Amazon やその他の書店でご利用いただけます。
この本を購入することで、Lua プロジェクトを支援することもできます。
![]() |
プログラミング inLua | ![]() |
第 2 部 テーブルとオブジェクト 第 17 章 弱参照テーブル |
第 13.4.3 節で、非 nil のデフォルト値を持つテーブルを実装する方法について論じました。具体的な手法を 1 つ取り上げ、他の 2 つの手法は弱参照テーブルを必要とするので後回しにしています。今こそそのテーマを見直す時です。後でわかるように、デフォルト値のそれらの 2 つの手法は、ここで見た 2 つの一般的な手法、オブジェクト属性とメモ化の具体的な応用です。
最初のソリューションでは、弱参照テーブルを使用して、各テーブルにそのデフォルト値を関連付けます
local defaults = {} setmetatable(defaults, {__mode = "k"}) local mt = {__index = function (t) return defaults[t] end} function setDefault (t, d) defaults[t] = d setmetatable(t, mt) end
defaults
に weak キーがない場合、デフォルト値を持つすべてのテーブルが永続的な存在に固定されます。2 番目のソリューションでは、異なるデフォルト値に異なるメタテーブルを使用しますが、デフォルト値を繰り返す場合は同じメタテーブルを再利用します。これは、メモ化の代表的な使用方法です
local metas = {} setmetatable(metas, {__mode = "v"}) function setDefault (t, d) local mt = metas[d] if mt == nil then mt = {__index = function () return d end} metas[d] = mt -- memoize end setmetatable(t, mt) endこの場合、使用されなくなったメタテーブルの収集を許可するために弱参照値を使用します。
デフォルト値のこれらの 2 つの実装を考えると、どちらが最善ですか? いつものように、それは状況次第です。どちらも複雑さは似ており、パフォーマンスも似ています。1 番目の実装では、デフォルト値を持つ各テーブルに対して少しの単語が必要になります (defaults
内のエントリ)。2 番目の実装では、異なるデフォルト値ごとに数十の単語が必要になります (新しいテーブル、新しいクロージャー、metas
内のエントリ)。したがって、アプリケーションに少数の異なるデフォルト値を持つ何千ものテーブルがある場合、2 番目の実装は明らかに優れています。一方、共通のデフォルトを共有するテーブルがほとんどない場合は、1 番目の実装を使用する必要があります。
著作権 © 2003–2004 Roberto Ierusalimschy。無断複写禁止。 | ![]() |