この初版は 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。無断複写禁止。 | ![]() |