明示的な「self」
CoddyのLuaジャーニー「Object Oriented Programming」セクションの一部 — レッスン 2/70。
関数がテーブル内にある場合、その同じテーブル内のデータにアクセスしたり、変更したりする必要があることがよくあります。しかし、ここで問題があります。関数は自分がどのテーブルに属しているかをどうやって知るのでしょうか?
解決策は、テーブルを関数の最初の引数として明示的に渡すことです。慣習として、このパラメータは self と名付けられます:
local counter = {
value = 0
}
function counter.increment(self)
self.value = self.value + 1
end
counter.increment(counter)
print(counter.value) -- 出力: 1どのように counter.increment(counter) を呼び出し、テーブル自体を引数として渡しているかに注目してください。関数内では、self はそのテーブルを指しており、これによって self.value を読み取ったり変更したりできるようになります。
このパターンは、テーブル名をハードコーディングすることなく、関数がテーブルのデータを操作できるようにするために不可欠です。現在のカウントをリセットして返す関数を考えてみましょう:
function counter.reset(self)
local old = self.value
self.value = 0
return old
end
print(counter.reset(counter)) -- 出力: 1
print(counter.value) -- 出力: 0テーブルを手動で渡すことでも機能しますが、繰り返しのように感じられることがあります。次のレッスンでは、これを自動的に処理する、より洗練された構文について学びます。
チャレンジ
簡単count フィールドを 0 で初期化した、tracker という名前のテーブルを作成してください。
以下の処理を行う関数 tracker.addAmount(self, amount) を追加してください:
- 第1引数として
self(テーブル自身) を受け取る - 第2引数として
amountを受け取る self.countにamountを加算する
2つの入力を受け取ります:
- 加算する1つ目の数値
- 加算する2つ目の数値
tracker.addAmount を2回呼び出し(各入力に対して1回ずつ)、毎回第1引数としてテーブルを渡してください。両方の呼び出しが終わった後、tracker.count の最終的な値を出力してください。
チートシート
テーブル内の関数は、慣習的に self と名付けられる最初のパラメータとしてテーブルを受け取ることで、テーブルのデータにアクセスできます:
local counter = {
value = 0
}
function counter.increment(self)
self.value = self.value + 1
end
counter.increment(counter) -- 引数としてテーブルを渡す
print(counter.value) -- 出力: 1self パラメータを使用すると、関数はテーブル名をハードコーディングすることなく、テーブルのフィールドを読み取ったり変更したりできます:
function counter.reset(self)
local old = self.value
self.value = 0
return old
end
print(counter.reset(counter)) -- 出力: 1
print(counter.value) -- 出力: 0関数は self の後に追加のパラメータを受け取ることができます:
function counter.add(self, amount)
self.value = self.value + amount
end
counter.add(counter, 5)自分で試してみよう
-- 入力を読み込む
local amount1 = tonumber(io.read())
local amount2 = tonumber(io.read())
-- TODO: 以下にコードを記述してください
-- 'count' フィールドを 0 で初期化した 'tracker' という名前のテーブルを作成します
-- self.count に amount を加算する関数 tracker.addAmount(self, amount) を追加します
-- テーブルを第1引数として tracker.addAmount を2回呼び出します
-- 最終的なカウントを出力します
print(tracker.count)このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。