Menu
Coddy logo textTech

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

カスタム演算子の動作を定義するこの能力は、演算子のオーバーロードと呼ばれます。

challenge icon

チャレンジ

簡単

x1y1x2y2 を受け取り、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
quiz icon腕試し

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

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