Kotlinのwhen文について

採用はこちら

Kotlinの when は、他言語の switch 文を発展させた構文であり、単なる条件分岐を超えて 「式(expression)」として値を返せる という大きな特徴を持っています。

その柔軟性と安全性から、Kotlinでは if-else よりも when が選ばれる場面が多く、言語設計の思想を強く反映した機能のひとつです。

本記事では、when の基本から応用、そして実務での使いどころまでを体系的に解説します。

目次

whenの基本構文

最も基本的な when の形は次の通りです。

val x = 3

when (x) {
    1 -> println("1です")
    2 -> println("2です")
    3 -> println("3です")
    else -> println("その他")
}

特徴

  • when (対象) に対して条件を列挙する
  • 各分岐は -> で処理を記述する
  • break は不要
  • 一致した分岐のみが実行され、フォールスルーは存在しない

Javaの switch に慣れている場合でも、より安全で直感的に扱えるのが when の利点です。

whenは「式」として値を返せる

Kotlinにおける when の本質は、値を返す式として使える点にあります。

val result = when (x) {
    1 -> "one"
    2 -> "two"
    3 -> "three"
    else -> "other"
}

この場合、when 全体がひとつの値として評価され、result に代入されます。

注意点

  • 式として使う場合、すべての分岐で値を返す必要がある
  • 分岐の戻り値は 共通の型に推論 される
    (型が揃っていないと Any に推論されることがあり、可読性や安全性が下がる)

実務では、同じ型を返すよう設計するのが基本です。

複数の値をまとめて分岐する

when では、カンマ区切りで複数の値をひとつの分岐にまとめられます。

when (x) {
    1, 2, 3 -> println("小さい数")
    4, 5 -> println("中くらい")
    else -> println("大きい")
}

これは論理 OR に相当し、冗長な条件分岐を避けられます。

範囲(range)による分岐

数値の連続した条件には、範囲指定が有効です。

val score = 85

when (score) {
    in 90..100 -> println("A")
    in 80..89 -> println("B")
    in 70..79 -> println("C")
    else -> println("D")
}
  • in は「範囲に含まれるか」の判定
  • 条件の意図がコードから直感的に読み取れる

点数・年齢・金額など、実務でも頻出の書き方です。

引数なしwhen(条件分岐としての利用)

when は対象値を指定せず、条件そのものを列挙する形でも使えます。

when {
    score >= 90 -> println("優秀")
    score >= 70 -> println("合格")
    else -> println("不合格")
}

特徴

  • 上から順に条件を評価し、最初に一致した分岐が実行される
  • if / else if / else をフラットに書き換えられる
  • 複雑なビジネスロジックでも可読性を保ちやすい

型判定(is / !is)とスマートキャスト

when は型による分岐にも対応しています。

fun printType(value: Any) {
    when (value) {
        is Int -> println("Intです")
        is String -> println(value.length)
        else -> println("不明な型")
    }
}
  • is による型チェックが可能
  • 分岐内では スマートキャスト により、明示的なキャストが不要になることが多い

※ ただし、var や不安定なプロパティの場合はスマートキャストされないケースもあります。

nullを含む分岐

null も通常の条件として扱えます。

when (value) {
    null -> println("nullです")
    is String -> println("文字列")
    else -> println("その他")
}

nullable型を扱う場面でも、安全かつ明確に条件分岐できます。

enum・sealed classとwhen(網羅性)

enumの場合

enum class Status {
    SUCCESS, ERROR, LOADING
}

val message = when (status) {
    Status.SUCCESS -> "成功"
    Status.ERROR -> "失敗"
    Status.LOADING -> "処理中"
}
  • すべての enum 定数を網羅していれば else は不要
  • enum に値を追加すると、コンパイル時に when の未対応箇所を検出できる

sealed classの場合

sealed class Result {
    data class Success(val data: String) : Result()
    data class Error(val message: String) : Result()
    object Loading : Result()
}

val text = when (result) {
    is Result.Success -> result.data
    is Result.Error -> result.message
    Result.Loading -> "読み込み中"
}
  • sealed class が「閉じた階層」として認識される場合、網羅性が保証される
  • 状態管理やUI分岐で非常に強力

複数行の処理を書く場合

各分岐ではブロックを書けます。

val value = when (x) {
    1 -> {
        println("ログ出力")
        x * 10
    }
    else -> 0
}

最後の式が戻り値になる点は、Kotlinらしい設計です。

if と when の使い分け

状況推奨
単純な2分岐if
3条件以上when
値・状態・型での分岐when
複雑な条件整理引数なしwhen

迷った場合は、可読性が高い方を選ぶのが基本です。

実務での注意点

不適切なelseに注意

else -> ""
  • 本来ありえない状態を隠してしまう可能性がある
  • 可能であれば else を省略するか、例外として明示的に扱う方が安全
else -> error("想定外の状態")

まとめ

Kotlinの when は、

  • 式として値を返せる
  • 値・範囲・条件・型・状態を一貫して扱える
  • enum / sealed class と組み合わせることで網羅性を確保できる

という点で、Kotlinらしい安全で宣言的なコードを書くための中核的な構文です。

単なる switch の代替としてではなく、設計を表現するための構文として使いこなすことで、Kotlinコードの品質は大きく向上します。

以上、Kotlinのwhen文についてでした。

最後までお読みいただき、ありがとうございました。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次