💪
引数の意味を明示するstrong type
以下のようにbool
型の引数を使っていませんか?
void createLevel(bool is_boss_level, bool add_save_point)
{
if (is_boss_level && add_save_point)
{
// ...
}
}
createLevel(true, false);
コールする側からすると、何がtrue
なのか、何がfalse
なのか全然分からないですよね。
以下のようにコメントが追加されるのはたまに見かけますが、この関数を呼ぶたびに、こういうコメントを書くのは大変です。
createLevel ( true /*is_boss_level*/
, false /*add_save_point*/
);
以下のようにそれっぽい名前の変数に代入して渡す手もあります。
const bool is_boss_level(true);
const bool add_save_point(false);
createLevel(is_boss_level, add_save_point);
でも毎回わざわざ変数を作成したくないですよね。しかも、同じbool
型なので、順番が間違っていても、コンパイルエラーにならないです。順番のミスはレビューで見逃しやすいですよね。
こういう場合は、専用の型というstrong type
が必要です。
一番簡単なやり方はenum class
を使うことです。普通のenum
は暗黙的に型変換されてしまうため、駄目です。
enum class Level { Normal, Boss };
enum class AddSavePoint{ Yes, No };
void createLevel(Level level, AddSavePoint add_save_point)
{
if (level == Level::Boss && add_save_point == AddSavePoint::Yes)
{
// ...
}
}
createLevel(Level::Boss, AddSavePoint::No);
createLevel(AddSavePoint::No, Level::Boss); // コンパイルエラー!
変数によって、変数名とenum class
の列挙子の名前を変えないといけなくなります。
でもこれだとコールする側から見ても、何を渡しているのかが分かりやすいです💪
順番を間違えて渡すとちゃんとコンパイルエラーになります💪💪
是非使ってみてください💪💪💪
あと、enum
とenum class
の違いについては別の記事に書いていますので、是非こちらも見てみてください。
Discussion