🐳
Whenでenumを見る時はelseは危険説
何が言いたい?
基本的にKotlinのWhenでenumをを使う時は else
は使わないほうがいいのでは。ということが言いたい
前提
- 私は普段Androidアプリ開発をしています
- Google I/Oアプリで使われている <T>.checkAllMatched を参考にしています
https://github.com/google/iosched/blob/main/shared/src/main/java/com/google/samples/apps/iosched/shared/util/Extensions.kt#L106-L107- whenでenumを見る時に最後につけておくと、条件でenumの項目がひとつでも抜けていたらビルドエラーになってくれる。実装時に抜けていたら気付けるし、enumに項目が増えた時にも気付ける便利なもの
kotlin
/**
* Helper to force a when statement to assert all options are matched in a when statement.
*
* By default, Kotlin doesn't care if all branches are handled in a when statement. However, if you
* use the when statement as an expression (with a value) it will force all cases to be handled.
*
* This helper is to make a lightweight way to say you meant to match all of them.
*
* Usage:
*
* ```
* when(sealedObject) {
* is OneType -> //
* is AnotherType -> //
* }.checkAllMatched
*/
val <T> T.checkAllMatched: T
get() = this
なぜ?
もしwhen内でelseを使っていた状態でenumに項目が増えた場合、本当に増えた項目がelseのロジックに入ってよいかどうかは誰もわからない
なのにelseを使っていると、意図せずelseに入ってしまい、バグを生み出してしまう可能性がある
じゃぁどうするか
- 基本的にはwhen内ではenumを個別に定義し、
.checkAllMatched
を用いる - whenではelseは基本的には使わない。同じ処理をしたい項目が多い場合でもカンマつなぎにする
- 明確な仕様として「enumのこれとこれは処理を定義し、他はまとめる。絶対に。」というものがあれば柔軟にすればよい
Discussion
sealed classで
when(A) { is B -> }
するときも同じことが言えそうですね!