Kotlinの三項演算子について

採用はこちら

Kotlinには、JavaやC言語系で使われる三項演算子 条件 ? A : B はありません。

たとえば Java では、次のように書けます。

String result = score >= 60 ? "合格" : "不合格";

しかし、Kotlinではこの書き方はできません。

その代わり、Kotlinでは if を式として使える ため、三項演算子の代わりに if 式を使います。

val result = if (score >= 60) "合格" else "不合格"

つまり、Kotlinでは

  • ? : の三項演算子は存在しない
  • その代わりに if (...) ... else ... を使う

というのが基本です。

目次

Kotlinで三項演算子が不要な理由

Kotlinでは if式として使えるため、条件によって値を返す処理をそのまま書けます。

そのため、Javaのような三項演算子を別に用意しなくても、同じことを自然に表現できます。

たとえば、大小比較で大きい方を代入したい場合はこう書けます。

val max = if (a > b) a else b

このように、if の結果をそのまま変数へ代入できます。

基本的な書き方

もっとも基本的な形は次の通りです。

val message = if (isMember) "会員です" else "ゲストです"

これは Java の三項演算子に対応する書き方です。

Java ならこうなります。

String message = isMember ? "会員です" : "ゲストです";

if を式として使うとはどういうことか

Kotlinでは if の結果が値になるため、さまざまな場所で使えます。

変数に代入する

val fee = if (age < 12) 500 else 1000

関数の引数として使う

println(if (isLoggedIn) "ログイン中" else "未ログイン")

return に直接使う

fun getStatus(score: Int): String {
    return if (score >= 60) "合格" else "不合格"
}

さらに短く書くとこうなります。

fun getStatus(score: Int): String = if (score >= 60) "合格" else "不合格"

複数行でも書ける

if 式は、各分岐をブロックで書くこともできます。

その場合、各ブロックの最後の式が、その分岐の値になります。

val result = if (score >= 60) {
    println("合格ラインを超えています")
    "合格"
} else {
    println("合格ライン未満です")
    "不合格"
}

この例では、

  • 条件が true のときは "合格"
  • false のときは "不合格"

result に入ります。

else は必要か

式として使うなら else は必要

if を値として使う場合は、else を省略できません。

val text = if (flag) "ON" else "OFF"

これは正しいコードです。

一方、次のコードはエラーになります。

val text = if (flag) "ON"

なぜなら、flag が false のときに何を返すのか決まっていないからです。

条件分岐として使うだけなら else は不要

if (flag) {
    println("ONです")
}

この場合は値を返す目的ではなく、単なる条件分岐として使っているので問題ありません。

Javaの三項演算子との対応

Javaで次のように書いていた処理は、

int discount = isVip ? 200 : 0;

Kotlinでは次のように書きます。

val discount = if (isVip) 200 else 0

また、Javaで null チェックと一緒に三項演算子を使っていたものも、Kotlinでは if で表現できます。

String label = value == null ? "未設定" : value;

Kotlinならこうです。

val label = if (value == null) "未設定" else value

?: は三項演算子ではない

ここは特に混同しやすいポイントです。

Kotlinには次のような記法があります。

val name = inputName ?: "名無し"

これは三項演算子ではなく、Elvis演算子 と呼ばれます。

意味は次の通りです。

  • 左辺が null でなければ左辺を使う
  • 左辺が null なら右辺を使う

つまり、次の if 式に近い意味です。

val name = if (inputName != null) inputName else "名無し"

三項演算子と Elvis演算子の違い

Javaの三項演算子

condition ? a : b

これは、条件式が true か false かで分岐します。

Kotlinの Elvis演算子

value ?: fallback

これは、左辺が null かどうかで分岐します。

比較すると

val result1 = if (score >= 60) "合格" else "不合格"
val result2 = name ?: "名無し"
  • result1 は条件分岐
  • result2 は null のときの代替値指定

という違いがあります。

分岐が増える場合

二択なら if で十分ですが、条件が増えると when のほうが読みやすいことがあります。

val rank = if (score >= 90) {
    "A"
} else if (score >= 80) {
    "B"
} else if (score >= 70) {
    "C"
} else {
    "D"
}

これでも問題ありませんが、Kotlinでは when を使うとより整理しやすいです。

val grade = when {
    score >= 90 -> "S"
    score >= 80 -> "A"
    score >= 70 -> "B"
    score >= 60 -> "C"
    else -> "D"
}

実務では、

  • 2分岐なら if
  • 多分岐なら when

という使い分けがよく行われます。

if 式の型について

if は式なので、結果には型があります。

同じ型を返す場合

val result = if (flag) "OK" else "NG"

この場合、resultString になります。

異なる型を返す場合

val value = if (flag) 100 else "エラー"

このように分岐ごとに型が大きく違うと、コードが読みにくくなり、扱いづらくなることがあります。

そのため、通常は分岐の結果の型をそろえるのが基本です。

たとえば、文字列として扱いたいなら次のようにそろえます。

val value: String = if (flag) "100" else "エラー"

実務でよくある使い方

表示文言の切り替え

val buttonText = if (isEditing) "更新する" else "作成する"

状態に応じた文字列の切り替え

val statusClass = if (isActive) "active" else "inactive"

null安全と組み合わせる

val displayName = if (!user.name.isNullOrBlank()) user.name else "名無し"

あるいは、Kotlinらしく書くならこうです。

val displayName = user.name?.takeIf { it.isNotBlank() } ?: "名無し"

Java経験者が間違えやすい点

三項演算子を書こうとしてしまう

val result = score >= 60 ? "合格" : "不合格"

これは Kotlin では使えません。

正しくはこうです。

val result = if (score >= 60) "合格" else "不合格"

?: を三項演算子だと思ってしまう

val name = input ?: "default"

これは Elvis演算子です。

条件式による true / false の分岐ではありません。

式として使っているのに else を省略する

val text = if (flag) "YES"

これはエラーになります。

分岐ごとの型をばらばらにする

val result = if (flag) 1 else "NG"

書ける場面はありますが、通常は避けたほうが読みやすく安全です。

可読性のコツ

1行で意味が明確ならそのままでよい

val msg = if (success) "成功" else "失敗"

条件が長いなら改行する

val message =
    if (user != null && user.isActive && user.point > 100) {
        "特別会員"
    } else {
        "通常会員"
    }

分岐が多いなら when を使う

val category = when {
    age < 13 -> "子ども"
    age < 20 -> "未成年"
    else -> "成人"
}

まとめ

Kotlinでは、

  • Javaのような三項演算子 condition ? a : b はない
  • 代わりに if を式として使う
  • ?: は三項演算子ではなく Elvis演算子
  • if を式として使うなら else が必要
  • 多分岐なら when が便利

このように理解すると整理しやすいです。

Javaの三項演算子を Kotlin に置き換えるときは、次の形で覚えるとわかりやすいです。

Java

condition ? a : b

Kotlin

if (condition) a else b

つまり、Kotlinでは三項演算子そのものはありませんが、if 式がその役割をそのまま担っていると考えると理解しやすいです。

以上、Kotlinの三項演算子についてでした。

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

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