Menu
Coddy logo textTech

算術メタメソッド パート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 * 22 * 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

これらのメタメソッドは、カスタム型の基本的な算術演算を完成させ、数学演算子がテーブルに対してどのように振る舞うかを完全に制御できるようにします。

challenge icon

チャレンジ

簡単

xy、および scalar を受け取り、スケーリングされたベクトルをフォーマット済み文字列として返す関数 scaleVector を作成してください。

指定された座標でベクトルテーブルを作成し、スカラー乗算を可能にするために __mul メタメソッドを持つメタテーブルをアタッチし、* 演算子を使用してベクトルとスカラーを乗算し、その結果を返します。

ロジック:

  • 提供された座標を xy キーに設定したベクトルテーブルを作成します
  • ベクトルとスカラーの間の乗算を処理する __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 * 22 * 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
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

Logic & Flowのすべてのレッスン