算術メタメソッド パート2
CoddyのLuaジャーニー「Logic & Flow」セクションの一部 — レッスン 22/54。
加算と減算に加えて、__mul および __div メタメソッドを使用して、テーブルの乗算と除算の動作を定義することもできます。これらは __add や __sub と同じように機能しますが、* および / 演算子に対応します。
__mul メタメソッドは、テーブルの値をスケーリングしたい場合に特に便利です。例えば、ベクトルに数値(スカラーと呼ばれます)を掛けると、各成分が乗算されるはずです:
local vector = {x = 3, y = 4}
local meta = {
__mul = function(a, b)
local scalar = type(a) == "number" and a or b
local vec = type(a) == "table" and a or b
return {x = vec.x * scalar, y = vec.y * scalar}
end
}
setmetatable(vector, meta)
local scaled = vector * 2
print(scaled.x, scaled.y) -- 出力: 6 8関数がどのオペランドが数値で、どちらがテーブルであるかを確認していることに注目してください。これにより、vector * 2 と 2 * vector の両方が正しく動作するようになります。
__div メタメソッドは、除算に対しても同様に機能します:
local meta = {
__div = function(a, b)
return {x = a.x / b, y = a.y / b}
end
}
setmetatable(vector, meta)
local divided = vector / 2
print(divided.x, divided.y) -- 出力: 1.5 2これらのメタメソッドは、カスタム型の基本的な算術演算を完成させ、数学演算子がテーブルに対してどのように振る舞うかを完全に制御できるようにします。
チャレンジ
簡単x、y、および scalar を受け取り、スケーリングされたベクトルをフォーマット済み文字列として返す関数 scaleVector を作成してください。
指定された座標でベクトルテーブルを作成し、スカラー乗算を可能にするために __mul メタメソッドを持つメタテーブルをアタッチし、* 演算子を使用してベクトルとスカラーを乗算し、その結果を返します。
ロジック:
- 提供された座標を
xとyキーに設定したベクトルテーブルを作成します - ベクトルとスカラーの間の乗算を処理する
__mulを持つメタテーブルを作成します __mul関数は、どちらのオペランドが数値で、どちらがテーブルであるかを確認する必要がありますx = vec.x * scalarおよびy = vec.y * scalarを持つ新しいテーブルを返しますsetmetatable()を使用してメタテーブルをベクトルテーブルにアタッチしますvector * scalarを使用してベクトルとスカラーを乗算します- 結果を
"x y"形式(xとyの値をスペースで区切ったもの)の文字列として返します
パラメータ:
x(number): ベクトルのx座標y(number): ベクトルのy座標scalar(number): ベクトルに乗算するスカラー値
戻り値: スケーリングされたベクトルを "x y" 形式の文字列として返します (string)
チートシート
__mul と __div メタメソッドは、テーブルの乗算と除算の動作を定義し、* および / 演算子に対応します。
__mul メタメソッドは、テーブルの値をスケーリングするのに便利です。ベクトルにスカラーを掛ける際、vector * 2 と 2 * vector の両方を可能にするために、どちらのオペランドが数値で、どちらがテーブルであるかを確認します。
local vector = {x = 3, y = 4}
local meta = {
__mul = function(a, b)
local scalar = type(a) == "number" and a or b
local vec = type(a) == "table" and a or b
return {x = vec.x * scalar, y = vec.y * scalar}
end
}
setmetatable(vector, meta)
local scaled = vector * 2
print(scaled.x, scaled.y) -- 出力: 6 8__div メタメソッドも、除算に対して同様に機能します:
local meta = {
__div = function(a, b)
return {x = a.x / b, y = a.y / b}
end
}
setmetatable(vector, meta)
local divided = vector / 2
print(divided.x, divided.y) -- 出力: 1.5 2自分で試してみよう
function scaleVector(x, y, scalar)
-- ここにコードを書いてください
end
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。