算術メタメソッド パート1
CoddyのLuaジャーニー「Logic & Flow」セクションの一部 — レッスン 21/54。
__tostring を使用して、テーブルをプリントしたときに何が起こるかをカスタマイズする方法を学びました。今度は、メタテーブルを使用して、テーブルに対して + や - などの算術演算子を使用したときに何が起こるかを定義できることも学びます。
通常、+ 演算子を使って2つのテーブルを加算しようとすると、Luaはテーブルの加算方法がわからないためエラーを返します。しかし、算術メタメソッドを使用すると、カスタムデータ型に対して加算が何を意味するのかを正確に定義できます。
__add メタメソッドは加算の動作を制御します。Luaが2つの値の間で + 演算子を検出し、少なくとも一方が __add を持つメタテーブルを持っている場合、エラーを発生させる代わりにその関数を呼び出します。
local v1 = {x = 3, y = 4}
local v2 = {x = 1, y = 2}
local meta = {
__add = function(a, b)
return {x = a.x + b.x, y = a.y + b.y}
end
}
setmetatable(v1, meta)
setmetatable(v2, meta)
local v3 = v1 + v2
print(v3.x, v3.y) -- 出力: 4 6__add 関数は、左オペランドと右オペランドの2つの引数を受け取ります。この例では、両方の入力テーブルの対応する値の合計であるxとyの値を持つ、新しいテーブルを作成します。
同様に、__subメタメソッドは-演算子による減算を制御します。
local meta = {
__sub = function(a, b)
return {x = a.x - b.x, y = a.y - b.y}
end
}
setmetatable(v1, meta)
setmetatable(v2, meta)
local v3 = v1 - v2
print(v3.x, v3.y) -- 出力: 2 2カスタム演算子の動作を定義するこの能力は、演算子のオーバーロードと呼ばれます。
チャレンジ
簡単x1、y1、x2、y2 を受け取り、2つのベクトルを加算した結果を返す関数 addVectors を作成してください。
指定された座標を持つ2つのベクトルテーブルを作成し、ベクトルの加算を可能にするために __add メタメソッドを持つメタテーブルをアタッチし、+ 演算子を使用してそれらを加算し、その結果をフォーマットされた文字列として返します。
ロジック:
- キー
x = x1およびy = y1を持つ最初のベクトルテーブルを作成します - キー
x = x2およびy = y2を持つ2番目のベクトルテーブルを作成します - 2つのベクトルを受け取り、
x = a.x + b.xおよびy = a.y + b.yを持つ新しいテーブルを返す__addを含むメタテーブルを作成します setmetatable()を使用して、両方のベクトルテーブルにメタテーブルをアタッチしますv1 + v2を使用して2つのベクトルを加算します- 結果を
"x y"の形式(xとyの値をスペースで区切ったもの)の文字列として返します
パラメータ:
x1(数値): 最初のベクトルのx座標y1(数値): 最初のベクトルのy座標x2(数値): 2番目のベクトルのx座標y2(数値): 2番目のベクトルのy座標
戻り値: 2つのベクトルの合計を "x y" 形式の文字列として返します (string)
チートシート
メタテーブルを使用すると、テーブルに対して + や - などの算術演算子を使用したときに何が起こるかを定義できます。これは演算子オーバーロードと呼ばれます。
__add メタメソッドは、+ 演算子による加算の動作を制御します。
local v1 = {x = 3, y = 4}
local v2 = {x = 1, y = 2}
local meta = {
__add = function(a, b)
return {x = a.x + b.x, y = a.y + b.y}
end
}
setmetatable(v1, meta)
setmetatable(v2, meta)
local v3 = v1 + v2
print(v3.x, v3.y) -- Output: 4 6__add 関数は、左オペランドと右オペランドの2つの引数を受け取ります。
__sub メタメソッドは、- 演算子による減算を制御します。
local meta = {
__sub = function(a, b)
return {x = a.x - b.x, y = a.y - b.y}
end
}
setmetatable(v1, meta)
setmetatable(v2, meta)
local v3 = v1 - v2
print(v3.x, v3.y) -- Output: 2 2自分で試してみよう
function addVectors(x1, y1, x2, y2)
-- ここにコードを書いてください
end
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。