🏋️‍♂️

【Kotlin学習記2】Kotlinは三項演算子が使えない。だがそこが良い!

に公開

前回の記事はこちらです。
https://zenn.dev/rickeysan/articles/6b7657654b7ac9

前回で環境構築が完了したので、早速簡単なアプリを作成しています。

そして、以下のドキュメントを参考にしながら、Compose のマテリアル コンポーネントを画面に表示させていきました。

https://developer.android.com/develop/ui/compose/components?hl=ja

そこで気づきました。

Kotlinは三項演算子が使えないということに(良い意味で)

ReactをJSX形式で書いていると、以下のようによく三項演算子を使っていました。

import React from "react";

export default function MembershipMessage({ memberStatus }) {
    return (
        <div className="p-4 rounded-xl shadow">
        {/* 三項演算子で会員ステータスを判定 */}
            <p>
            { memberStatus === "standard"
            ? "標準会員です"
            : "無料会員です"}
            </p>
        </div>
        );
    }

Kotlinでは、上記のように三項演算子による分岐ができません。if-else式やwhen式などを使う必要があります。

Kotlinでif式での記述

@Composable
fun MembershipMessage(memberStatus: String) {
    Box(
        modifier = Modifier
    ) {
        if (memberStatus == "standard") {
            Text("標準会員です")
        } else {
            Text("無料会員です")
        }
    }
}

もしくは、Kotlinでのwhen式での記述

Box(
    modifier = Modifier
) {
    when (memberStatus) {
        "standard" -> {
            Text("標準会員です")
        }
        else -> {
            Text("無料会員です")
        }
    }
}

このKotlinの仕様はすごく気に入りました。私はメインでPHPを使っていますが、PHPでは三項演算子は使えます。

$sample = ($memberStatus === "standard") ? "標準会員" : "無料会員";

三項演算子はわかりづらいと思っていましたが、あまり複雑にならないと(その当時は)思う時は、よく使っていました。

ただ、Kotlinはそれができません。選択肢として三項演算子が用意されていません。なので、以下のようにif文を式として書く必要があります。

val sample = if (memberStatus == "standard") "標準会員" else "無料会員"

選択肢として用意されていないので、ifで書かざるを得ません。

面倒かもしれませんが、拡張性を考えると有利だと思います。

上記のコンポーネントの例ですが、例えば、memberStatusに”premium”が追加されたとします。この時、文言も「プレミアム会員です」と表示させたいです。

こうなってくると、三項演算子で記述することが難しくなって、結局if文などでリファクタリングしなくてはなりません。

また、コードの視認性の面でも、三項演算子はない方が良いと思います。

コンポーネントを記述するコードは、引数が多いことがあり、三項演算子の?や:がどこにあるのかが、ぱっと見で分からないことがあります。

条件 ?
    大きなコンポーネントA
        (複数行)
        (複数行)
        (複数行)
    :
    大きなコンポーネントB
        (複数行)
        (複数行)
        (複数行)

上記よりも、ifとelseで明示的に書いてくれた方が、構造がすぐに理解できます。

if (条件) {
    大きなコンポーネントA
        (複数行)
        (複数行)
        (複数行)
    } else {
    大きなコンポーネントB
        (複数行)
        (複数行)
        (複数行)
}

ところで、Kotlinはどうして三項演算子の書き方を認めていないのかについて、下記のスレッドを見つけました。

https://www.reddit.com/r/Kotlin/comments/1cht4tm/why_is_there_no_classic_ternary_operator_in_kotlin/?tl=ja

Kotlinで ? が登場する他のすべての場所では、null許容性に関係しているため、可読性を損なう可能性があるということでした。Kotlinのコア設計の柱の一つは、null許容性処理を向上させることでした。

疑問符に関するすべてはヌルを指すという指摘は、まさに的を射ているね。

この理由からだと、?の代わりに他の記号を使って三項演算子を表現することもできたのではとも思いますが、他にも理由があると思います。

とりあえず、疑問符?に関わる記法は、全てnullが関係しているというのはとてもわかりやすいです。

まだ勉強を始めたばかりですが、少しKotlinのことが好きになりました。

Discussion