🐳

Whenでenumを見る時はelseは危険説

2022/10/02に公開1

何が言いたい?

基本的にKotlinのWhenでenumをを使う時は else は使わないほうがいいのでは。ということが言いたい

前提

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に入ってしまい、バグを生み出してしまう可能性がある

じゃぁどうするか

  1. 基本的にはwhen内ではenumを個別に定義し、 .checkAllMatched を用いる
  2. whenではelseは基本的には使わない。同じ処理をしたい項目が多い場合でもカンマつなぎにする
    1. 明確な仕様として「enumのこれとこれは処理を定義し、他はまとめる。絶対に。」というものがあれば柔軟にすればよい

Discussion

てべすてんてべすてん

sealed classでwhen(A) { is B -> } するときも同じことが言えそうですね!

sealed class Book
class ScienceBook:Book()
class Novel:Book()

when(someBook){
  is ScienceBook -> ...
  is Novel -> ...
  else -> ...  // 新しい本を追加するとエラーにならずここに来ちゃう!
}