🔰

【Go】if/else へのコメントで困ったこと

2024/11/11に公開2

コメント道は奥が深い

プログラムにどのようなコメントを残すのかは、人によって全然違います。N人N色。N差M別。

Aさん「半年先の自分は他人。コメントは将来の自分のためにもくどいくらい残しておくべき!」
Bさん「プログラムを読めばすぐわかるような冗長なコメントはむしろ残すべきではない。」
Cさん「適切な変数名とシンプルなロジックでコードを書いていればそもそもコメントなんて不要。」

いろんな宗派があります。

私は、Aさんを教祖とした新人教育を受けてきたこともあり、人よりも多めにコメントを残すタイプなのですが、Goのコーディングをしていて困ったことが起きました。

Goのif/elseのコメントで困ったケース

コメントたくさん残す派の私は、if/elseの各節にもコメントを残したくなってしまいます。
こんな具合です。

// ~~~の場合
if param == 0 {
    ...
// ~~~の場合
} else if param >= 1 && param <= 3 {
    ...
// ~~~の場合
} else {
    ...
}

しかし、ここで困ったことが起きます。
Goには公式が提供するフォーマッタである gofmt を使うという文化があるのですが、gofmt を使って上のコードが整形されるとどうなるかというと……

// ~~~の場合
if param == 0 {
    ...
    // ~~~の場合
} else if param >= 1 && param <= 3 {
    ...
    // ~~~の場合
} else {
    ...
}

こうなります。

else節の前行のコメントのインデントがズレてしまいました。ブロックの内側のコメントだと見なされてしまったようです。

解決方法は?

残念ながらありません。
gofmt はフォーマット方法を変更できないことがウリなので、gofmt を使う以上、この問題は絶対に解決できません(かといって、Gopherの端くれたる者 gofmt を使わないという選択肢はありません)。

解決方法がなくて悩みましたが、結局はこのようなコメントの残し方をそもそもやめるべきだと、考え方を変えることにしました。

考え方を変えよう

①コメントはif/elseブロック全体へ

プログラマの諸先輩方のコードを拝見させてもらったところ、if/elseにコメントを残している方はほとんどいないようでした。ここで、自分が冗長なコメントを残し過ぎなのではと気付いたのです。
残すべきは、コード一行一行に対する直訳コメントではなく、あるコードのまとまりで「何を行おうとしているのか」です。
今回はif/else全体がひとつのコードのまとまりであると考えられます(もっとも、単純なif/elseだったらコメント自体不要な場合もあります)。

// 下のif/else全体で何をしたいのかをコメントを書く
if param == 0 {
    ...
} else if param >= 1 && param <= 3 {
    ...
} else {
    ...
}

②補足するなら最小限に

それでもif/elseの節に対してコメントが必要なら、以下のように書くこともできます。

// 下のif/else全体で何をしたいのかをコメントを書く
if param == 0 {
    ...
} else if param >= 1 && param <= 3 { // 補足コメント
    ...
} else {
    ...
}

③if/else以外の書き方へのリファクタリング

そもそも、各節に対してコメントを書いておきたいようなケースって、if/elseというよりswitch/caseの方が相応しいコードなのかもしれません。
サンプルコードのように、ある一つの変数の値によって分岐するようなケースでは尚更です。

switch {
// ~~~の場合
case param == 0:
    ...
// ~~~の場合
case param >= 1 && param <= 3:
    ...
// ~~~の場合
default:
    ...
}

上記はGoの例ですが、case節に条件式を書けない言語、例えばC言語では次のような書き方になります。

switch(param) {
// ~~~の場合
case 0:
    ...
    break;
// ~~~の場合
case 1:
case 2:
case 3:
    ...
    break;
// ~~~の場合
default:
    ...
    break;
}

おわりに

Goのコードフォーマッタが、コメントの残し方について見つめ直す良いきっかけとなりました。私と同じようにコメントたくさん残す派の方がGoのif/elseで困ったとき、この記事がちょっとした助けになれば幸いです。これからプログラミングを学ぶ方は、今のうちから最適なコメントの残し方を意識しておくことをオススメします。

Discussion

rakiraki

else にコメント書きたいほど複雑だとか難解な if 文ならブロックの内側にコメントがあっていい気がする。。。

	// param の値によって動作を変える
	// この例が酷いことは認める。が、今のところ問題がない
	// 対応する処理が出揃ったら切り出して構わない
	if param == 0 {
		// 0 の場合は◯◯
		// ◯◯処理
	} else if param >= 1 && param <= 3 {
		// 1 か 2 か 3 の場合は△△
		// △△処理
	} else {
		// いずれでもない場合は✕✕するべき
		//本来はここに落ちるべきではない
		// ✕✕
	}
bugph0biabugph0bia

コメントありがとうございます。
たしかに内側に書くこともできますね。分岐自体を説明する場合のコメントは、ブロックの外側に書くことに固執してしまっていました💦