ドット vs コロン
CoddyのLuaジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 4/70。
ドット構文とコロン構文の両方がわかったところで、それらの関係と、テーブルが渡されないと何が起こるかを見ていきましょう。
どちらのコロンも省略記法です。function game:addPoints(points)を定義することは、function game.addPoints(self, points)を定義することと同じです。また、game:addPoints(10)を呼び出すことは、game.addPoints(game, 10)を呼び出すことと同じです。テーブルが最初の引数として渡されれば、メソッドは動作します。
テーブルが渡されない場合に何が起こるかを見てみましょう。
local game = { score = 0 }
function game:addPoints(points)
self.score = self.score + points
end
-- WRONG: ドットで呼び出しているが、テーブルを渡していない
game.addPoints(10) -- エラー!self はテーブルではなく 10 になっているgame.addPoints(10)を呼び出しても、Luaは自動的にgameを渡しません。値10がselfになり、10はテーブルではなく数値なので、self.scoreは失敗します。
ドットと明示的なselfを使って定義された関数は、コロン呼び出しで動作します。コロンはそのテーブルを最初の引数として渡すためです。
function game.reset(self)
self.score = 0
end
-- コロンを使った呼び出し: game:reset() は game.reset(game) と同じ
game:reset() -- self に game が正しく渡されるため、これは動作するどちらの定義でも同じ関数が作られるため、どちらを使うかは慣習によります。self を使う関数の定義や呼び出しにはコロンを使い、self を使わない関数にはドットを使います。そうすれば、各呼び出しでテーブルが渡されるかどうかが分かります。
チャレンジ
簡単playerという名前のテーブルを作成し、scoreフィールドを0で初期化します。
テーブルに2つの関数を追加します。
player.setScore(self, value)- ドット構文で定義し、selfパラメーターを明示的に指定します。self.scoreに指定された値を設定します。player:addBonus(amount)- コロン構文で定義します。amountをself.scoreに加算します。
2つの入力が与えられます。
- 初期スコア値
- 加算するボーナス量
次の手順を実行します。
- ドット構文を使って
setScoreを呼び出し(テーブルを最初の引数として渡し)、初期スコアを設定します。 - コロン構文を使って
addBonusを呼び出し、ボーナスを加算します。 player.scoreの最終値を出力します。
各関数の呼び出し方は、その関数の定義方法に合わせてください。
自分で試してみよう
-- 入力を読み込む
local initialScore = tonumber(io.read())
local bonusAmount = tonumber(io.read())
-- TODO: 以下にコードを書く
-- 1. 'score' フィールドを 0 で初期化した 'player' という名前のテーブルを作成する
-- 2. self を明示し、ドット構文で player.setScore(self, value) を追加する
-- 3. コロン構文で player:addBonus(amount) を追加する
-- 4. ドット構文で setScore を呼び出す(最初の引数としてテーブルを渡す)
-- 5. コロン構文で addBonus を呼び出す
-- 最終スコアを出力する
print(player.score)このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
自分で練習してみよう: Luaオンラインコンパイラ