Kotlin初心者向け:三項演算子を使わずシンプルに条件分岐する方法
はじめに:Kotlinと条件分岐の世界へようこそ!
Kotlinの世界へようこそ!プログラミングを始めたばかりの皆さんにとって、「条件分岐」は避けて通れない、かつ非常に重要な概念です。「もし〇〇だったら、Aの処理をする。そうでなければ、Bの処理をする」のように、プログラムの流れを状況に応じて変えることができなければ、できることは限られてしまいます。
多くのプログラミング言語には、この条件分岐を実現するための様々な構文が用意されています。中でも、一部の言語に存在する「三項演算子」は、短い条件分岐を1行で記述できる便利な構文として知られています。例えば、JavaやC++では 条件 ? 真の場合の値 : 偽の場合の値
のように書きます。
しかし、Kotlinには、この一般的な形式の「三項演算子」は存在しません。これを聞いて、「どうやって短い条件分岐を書けばいいんだろう?」「Kotlinは不便なのかな?」と感じる方もいるかもしれません。
安心してください!Kotlinには、三項演算子がなくても、あるいはそれ以上にシンプルかつ強力に条件分岐を記述できる方法がいくつも用意されています。Kotlinが三項演算子をあえて採用しなかったのは、Kotlinが目指す「読みやすく、書きやすいコード」という哲学に基づいています。Kotlinは、従来の三項演算子の利便性を持ちつつ、その欠点(例えば、ネストした際の読みにくさなど)を克服する代替手段を提供しています。
この記事では、Kotlin初心者の方が「三項演算子がない」ことを一切気にすることなく、むしろKotlinらしいシンプルで分かりやすい方法で条件分岐を記述できるようになることを目指します。基本的なif
文から始まり、Kotlin独自の強力な機能である「if
式」や「when
式」を使った条件分岐、さらにはNullableな値を扱う際に便利な「エルビス演算子」など、様々なテクニックを豊富なコード例とともに徹底的に解説します。
この記事を読み終える頃には、あなたはKotlinでの条件分岐に自信を持ち、より簡潔で表現豊かなコードを書けるようになっているはずです。さあ、Kotlinのシンプルでパワモビルな条件分岐の世界を一緒に探検しましょう!
この記事の対象読者:
* Kotlinを始めたばかりで、条件分岐の書き方を知りたい方
* 他の言語(Javaなど)で三項演算子を使った経験があり、Kotlinでの代替方法を知りたい方
* Kotlinの基本的な構文は理解しているが、よりKotlinらしい書き方を学びたい方
第1章:条件分岐の基本中の基本 – if
文
プログラミングにおける条件分岐の最も基本的な形は、多くの言語で共通して使われるif
文です。Kotlinにももちろんif
文は存在し、その基本的な使い方は他の言語とよく似ています。まずはここから始めて、条件分岐の考え方に慣れていきましょう。
1.1 if
文の基本的な構文
if
文は、「もし(if)特定の条件が真(true)であるならば、この処理を実行する」というように、条件が満たされた場合にのみ実行したいコードブロックを指定するために使用します。
基本的な構文は以下のようになります。
kotlin
if (条件式) {
// 条件式がtrueの場合に実行されるコード
}
if
キーワードの後には、丸括弧()
で囲まれた条件式を書きます。- 条件式は、評価結果が
Boolean
型(true
またはfalse
)になる式である必要があります。例えば、比較演算子(>
,<
,>=
,<=
,==
,!=
)を使った式や、論理演算子(&&
,||
,!
)を使った式などです。 - 条件式の後には、波括弧
{}
で囲まれたコードブロックを書きます。このブロック内のコードは、条件式がtrue
と評価された場合にのみ実行されます。
1.2 if
文を使ったシンプルなコード例
具体的な例を見てみましょう。ある数値が10より大きいかどうかを判定し、メッセージを表示するコードです。
“`kotlin
fun main() {
val number = 15
if (number > 10) {
println("数値は10より大きいです。")
}
}
“`
このコードを実行すると、number
は15
なので、条件式number > 10
はtrue
と評価されます。したがって、波括弧 {}
内のprintln("数値は10より大きいです。")
が実行され、「数値は10より大きいです。」というメッセージが表示されます。
もしnumber
を5
に変更して実行した場合、number > 10
はfalse
となるため、if
ブロック内のコードは実行されず、何も表示されません。
1.3 else
ブロック:条件が偽の場合の処理
if
文は、条件がtrue
の場合の処理を指定するものですが、「もし条件がfalse
だった場合に別の処理を実行したい」という状況もよくあります。このような場合に使うのがelse
ブロックです。
if
文にelse
ブロックを追加すると、構文は以下のようになります。
kotlin
if (条件式) {
// 条件式がtrueの場合に実行されるコード
} else {
// 条件式がfalseの場合に実行されるコード
}
例を見てみましょう。数値が10より大きいか、そうでないかで表示するメッセージを変えるコードです。
“`kotlin
fun main() {
val number = 8
if (number > 10) {
println("数値は10より大きいです。")
} else {
println("数値は10以下です。")
}
}
“`
このコードでは、number
は8
なので、number > 10
はfalse
と評価されます。この場合、if
ブロックはスキップされ、else
ブロック内のprintln("数値は10以下です。")
が実行されます。
1.4 else if
ブロック:複数の条件を判定する
二者択一ではなく、「もし〇〇だったらA、そうでなく(else if)△△だったらB、それ以外(else)だったらC」のように、複数の条件を順番に判定したい場合があります。このような場合に使うのがelse if
ブロックです。else if
ブロックはいくつでも連ねることができます。
構文は以下のようになります。
kotlin
if (最初の条件式) {
// 最初の条件式がtrueの場合に実行
} else if (次の条件式) {
// 最初の条件式がfalseで、次の条件式がtrueの場合に実行
} else if (さらに次の条件式) {
// ...
} else {
// どの条件式もtrueでなかった場合に実行 (elseブロックは省略可能)
}
例を見てみましょう。数値の範囲によってメッセージを変えるコードです。
“`kotlin
fun main() {
val score = 75
if (score >= 90) {
println("評価:優")
} else if (score >= 80) {
println("評価:良")
} else if (score >= 70) {
println("評価:可")
} else {
println("評価:不可")
}
}
“`
このコードでは、score
は75
です。
1. 最初の条件score >= 90
はfalse
です。
2. 次にelse if (score >= 80)
が評価されます。これはfalse
です。
3. 次にelse if (score >= 70)
が評価されます。これはtrue
です。したがって、このブロック内のprintln("評価:可")
が実行されます。
4. いずれかのif
またはelse if
ブロックが実行されると、それ以降のelse if
やelse
ブロックは評価されずにスキップされます。
このように、else if
を使うことで、複数の条件を効率的に、かつ読みやすく扱うことができます。条件は上から順番に評価され、最初にtrue
になったブロックだけが実行されます。
1.5 if
文の利点と欠点(文としての利用の場合)
利点:
* 分かりやすさ: if
文は多くのプログラミング言語で共通の基本的な構文であり、直感的に理解しやすいです。「もし〇〇なら、これをする」という自然言語に近い思考でコードを書くことができます。
* 可読性: 特に複数の処理を含むブロックの場合、{}
で囲まれたif
文やelse
文はコードの構造を明確にし、どのコードがどの条件に依存しているかが分かりやすいです。
* 複雑な処理: 条件が真または偽の場合に、複数の文からなる比較的複雑な処理を実行したい場合に適しています。
欠点:
* 冗長性: 非常に短い条件分岐、特に「条件が真ならこの値を使い、偽なら別の値を使う」といった単純なケースでは、if
文(特に文として使う場合)は少々冗長に感じられることがあります。変数宣言と値の代入を組み合わせる場合に特に顕著です。
例えば、「価格が1000円以上なら送料無料、それ以外は送料500円」という条件で送料を計算する場合、一般的なif
文(文として)で書くと以下のようになります。
“`kotlin
fun main() {
val price = 1200
val shippingCost: Int // まず変数を宣言
if (price >= 1000) {
shippingCost = 0 // 条件が真なら代入
} else {
shippingCost = 500 // 条件が偽なら代入
}
println("送料: $shippingCost 円") // 変数を利用
}
“`
このコードは正しく動作しますが、shippingCost
という変数を一度宣言し、if
とelse
それぞれのブロック内で値を代入するという手順が必要になります。このような「条件によって変数に代入する値を切り替える」というシンプルな目的のためだけに、数行のコードが必要になります。他の言語の三項演算子が便利なのは、まさにこのようなケースです。
しかし、心配いりません。Kotlinには、この課題を解決し、より簡潔に値を返す条件分岐を記述できる、非常に強力な機能が備わっています。それが次に説明する「if
式」です。
第2章:Kotlinらしい条件分岐 – if
式(Expression)として使う
Kotlinのif
は、多くの他の言語のように「文(Statement)」としてだけでなく、「式(Expression)」として値を返すことができます。これが、Kotlinに一般的な三項演算子が存在しない最大の理由の一つです。Kotlinのif
式を使えば、三項演算子のように短い記述で条件によって異なる値を返す処理を実現できます。
2.1 if
が式として値を返す仕組み
Kotlinにおいて、「式(Expression)」とは評価されて何らかの値を返すものです。「文(Statement)」は、評価されて何らかの「処理」を実行するものですが、値を直接は返しません。(ただし、Kotlinではほとんどの制御構造が式として値を返せるよう設計されています)
if
を式として使う場合、その構文はif
文と似ていますが、if
またはelse
ブロックの最後の式の値が、if
式全体の評価結果として返されます。
基本的な構文は以下のようになります。
kotlin
val result = if (条件式) {
// 条件式がtrueの場合に評価される最後の式の値が返される
値A
} else {
// 条件式がfalseの場合に評価される最後の式の値が返される
値B
}
if
ブロックとelse
ブロックは、それぞれ独自のコードを持つことができますが、値を返すためには、それぞれのブロックの最後の行に式を書く必要があります。その式の評価結果が、そのブロック全体の「返り値」となります。if
式を使う場合、else
ブロックは必須です。なぜなら、if
式は常に何らかの値を返さなければならないため、条件がtrue
の場合とfalse
の場合の両方で返すべき値が明確である必要があるからです。- 返される値の型は、
if
ブロックとelse
ブロックから返される値の型の共通のスーパータイプになります。通常は同じ型を使用することが推奨されます。
2.2 if
式を使った簡単な例:三項演算子の代替
先ほどの送料計算の例を、if
式を使って書き直してみましょう。
“`kotlin
fun main() {
val price = 1200
val shippingCost: Int = if (price >= 1000) {
0 // ifブロックの最後の行の値 (Int)
} else {
500 // elseブロックの最後の行の値 (Int)
}
println("送料: $shippingCost 円")
}
“`
このコードでは、if (price >= 1000) { 0 } else { 500 }
というif
式全体が評価され、その結果として得られた値(この場合は0
または500
)がshippingCost
という変数に代入されます。
注目すべきは、shippingCost
変数の宣言と値の代入が1行で済んでいる点です。従来のif
文のように、まず変数を宣言しておき、後でブロック内で代入する必要がありません。これは、三項演算子が提供していた簡潔さと非常によく似た利点です。
さらに、ブロックが単一の式で構成される場合は、波括弧 {}
を省略してより簡潔に書くことも可能です。
“`kotlin
fun main() {
val price = 1200
val shippingCost: Int = if (price >= 1000) 0 else 500 // さらに簡潔に!
println("送料: $shippingCost 円")
}
“`
これが、Kotlinにおいて一般的な三項演算子が存在しない理由の一つです。if
式をこのように記述することで、他の言語の三項演算子とほぼ同じ、あるいはそれ以上に簡潔で読みやすいコードで、条件によって値を切り替える処理を実現できます。
2.3 複数のelse if
を含むif
式
if
式も、else if
ブロックを組み合わせることで、複数の条件に基づいて値を返すことができます。この場合も、最後のelse
ブロックは必須です。
“`kotlin
fun main() {
val score = 75
val grade: String = if (score >= 90) {
"優" // ifブロックの最後の値
} else if (score >= 80) {
"良" // else ifブロックの最後の値
} else if (score >= 70) {
"可" // else ifブロックの最後の値
} else {
"不可" // elseブロックの最後の値
}
println("評価: $grade")
}
“`
このコードでは、score
の値に応じてif
/else if
/else
のいずれかのブロックが実行され、そのブロックの最後の行の値(文字列リテラル)がgrade
変数に代入されます。結果として「評価: 可」と表示されます。
ここでも、波括弧 {}
を省略して単一行で書くことも可能です。ただし、複数のelse if
が連なると、一行に書いた場合に読みにくくなる可能性もあります。可読性を考慮して、波括弧を付けるかどうか、複数行に分けるかどうかを判断しましょう。
kotlin
// 一行に書く例 (可読性は低下する可能性あり)
val grade: String = if (score >= 90) "優" else if (score >= 80) "良" else if (score >= 70) "可" else "不可"
2.4 コードブロックを返す場合
if
やelse
ブロックが複数の処理を含む場合でも、そのブロック全体が式として値を返すことができます。この場合、ブロック内の最後の式の結果がそのブロックの値となります。
“`kotlin
fun main() {
val time = 9
val greeting: String = if (time < 12) {
println("おはようございます!") // これは処理
"Good Morning" // この式の値がifブロックの返り値
} else if (time < 18) {
println("こんにちは!") // これは処理
"Good Afternoon" // この式の値がelse ifブロックの返り値
} else {
println("こんばんは!") // これは処理
"Good Evening" // この式の値がelseブロックの返り値
}
println("英語での挨拶: $greeting")
}
“`
この例では、各ブロック内でprintln
によるメッセージ表示という「処理」を行い、その後に文字列リテラルという「式」を置いています。この最後の文字列リテラルが、それぞれのブロックの「返り値」となり、それが最終的にgreeting
変数に代入されます。
実行結果は以下のようになります(time
が9の場合):
おはようございます!
英語での挨拶: Good Morning
このように、Kotlinのif
式は単に値を返すだけでなく、複数の処理を実行した上で最後に値を返すという柔軟な使い方もできます。これは、従来の三項演算子にはない大きな特徴です。
2.5 if
式の利点と注意点
利点:
* 簡潔性: 条件によって値を切り替えるような単純なケースで、非常に簡潔に記述できます。従来の三項演算子と同等以上の簡潔さを提供します。
* 柔軟性: ブロックとして複数の処理を含んだ上で値を返すことができます。
* 読みやすさ: 三項演算子よりも構文がif
文に近いため、ネストした場合でも比較的読みやすい傾向があります(ただし、あまり複雑な式にすると逆効果になることもあります)。
* 変数のイミュータビリティ: val
で宣言した変数に条件分岐の結果を一度に代入できるため、意図しない変数の再代入を防ぎ、イミュータブルなプログラミングスタイルを促進できます。
注意点:
* else
の必須性: 値を返すif
式として使う場合、else
ブロックは必須です。全ての実行パスで値を返さなければならないためです。(これはKotlinコンパイラがチェックしてくれます)
* 可読性: 非常に複雑な条件式や、各ブロック内の処理が多い・長い場合は、if
式として1行に詰め込むよりも、従来のif
文として複数行に分ける方が読みやすくなることがあります。常に可読性を意識して使い分けましょう。
if
式は、Kotlinで最も頻繁に使われる条件分岐の方法の一つです。特に、条件によって変数の値を決めたい、あるいは特定の式の結果を変えたいといった場合に、その真価を発揮します。三項演算子がないことに不便を感じるどころか、「Kotlinのif
式の方が強力で便利だ!」と感じられるはずです。
第3章:複数の条件をスマートに処理 – when
式
if-else if-else
を連ねることで複数の条件分岐を記述できますが、チェックしたい値に対して「〇〇の場合」「△△の場合」「□□の場合」… のように、特定の複数の可能性に対する処理を記述したい場面がよくあります。このような、特定の値をいくつかの可能性と照合して処理を分けるケースにおいて、Kotlinではwhen
式が非常に強力で役立ちます。
when
式は、他の言語におけるswitch
文(あるいはswitch
式)に相当する機能ですが、Kotlinのwhen
はより柔軟で表現力豊かです。そしてif
式と同様に、when
も式として値を返すことができます。
3.1 when
式の基本的な構文(引数あり)
特定の式(例えば変数)の値を評価し、その値がいくつかの指定された値のいずれかと一致するかどうかを判定して、対応する処理を実行する場合、when
に引数を渡します。
kotlin
when (評価対象の式) {
値1 -> {
// 評価対象の式が値1と一致する場合に実行されるコード
}
値2, 値3 -> {
// 評価対象の式が値2または値3と一致する場合に実行されるコード
}
in 範囲 -> {
// 評価対象の式が指定された範囲に含まれる場合に実行されるコード
}
is 型 -> {
// 評価対象の式が指定された型である場合に実行されるコード (スマートキャストも可能)
}
// ... 他の条件
else -> {
// 上記どの条件にも一致しなかった場合に実行されるコード (式として使う場合は必須)
}
}
when
キーワードの後には、丸括弧()
で囲まれた評価対象の式を書きます。- 波括弧
{}
の中には、条件 -> { 実行するコード }
の形式で分岐の条件とその場合に実行するコードを記述します。 - 条件部には、リテラル値、変数、式などを指定できます。
- 複数の条件をカンマ
,
で区切ってまとめて書くこともできます(例:値2, 値3
)。 in
演算子を使って、数値などの値が特定の範囲に含まれるかどうかを条件に指定できます。is
演算子を使って、オブジェクトの型を条件に指定できます。(!is
で型が一致しない場合を指定することも可能)else
ブロックは、どの条件にも一致しなかった場合に実行されます。when
を式として使う場合は、else
ブロックは必須です(全ての実行パスで値を返す必要があるため)。文として使う場合は、全ての可能性を網羅していることがコンパイラに証明できる場合(例えばEnumの全ての値を列挙した場合など)を除き、else
ブロックは推奨されるか、必須となります。
例を見てみましょう。数値に対応する曜日名を判定するコードです。
“`kotlin
fun main() {
val dayOfWeek = 3 // 1:月, 2:火, …, 7:日
when (dayOfWeek) {
1 -> println("月曜日")
2 -> println("火曜日")
3 -> println("水曜日")
4 -> println("木曜日")
5 -> println("金曜日")
6, 7 -> println("週末") // 6または7の場合
else -> println("不正な値です") // 1-7以外の場合
}
}
“`
このコードでは、dayOfWeek
が3
なので、3 -> println("水曜日")
が実行され、「水曜日」と表示されます。
もしdayOfWeek
が6
であれば、6, 7 -> println("週末")
が実行され、「週末」と表示されます。
もしdayOfWeek
が0
であれば、どの条件にも一致しないため、else -> println("不正な値です")
が実行されます。
単一の式を実行する場合は、->
の後に直接式を書くことができます。複数の式を実行する場合は、波括弧 {}
で囲みます。
kotlin
when (dayOfWeek) {
1 -> {
println("今日は平日です")
println("月曜日")
}
// ... 他の分岐
}
3.2 when
式も値を返す – if
式よりも複雑な分岐に
when
式もif
式と同様に、式として値を返すことができます。この場合、一致した条件ブロックの最後の式の値が、when
式全体の評価結果として返されます。
構文はif
式の場合と似ています。
kotlin
val result = when (評価対象の式) {
値1 -> 値A // 値1に一致した場合に返される値
値2, 値3 -> 値B // 値2または値3に一致した場合に返される値
// ... 他の条件
else -> 値C // どの条件にも一致しなかった場合に返される値
}
例を見てみましょう。数値に対応する曜日名を文字列として取得するコードです。
“`kotlin
fun main() {
val dayOfWeek = 5 // 1:月, 2:火, …, 7:日
val dayName: String = when (dayOfWeek) {
1 -> "月曜日"
2 -> "火曜日"
3 -> "水曜日"
4 -> "木曜日"
5 -> "金曜日"
6 -> "土曜日"
7 -> "日曜日"
else -> "不明な曜日" // 式として使うのでelseは必須
}
println("今日は $dayName です")
}
“`
このコードでは、dayOfWeek
が5
なので、5 -> "金曜日"
が評価され、文字列"金曜日"
がdayName
変数に代入されます。結果として「今日は 金曜日 です」と表示されます。
波括弧を省略しない場合も、ブロックの最後の行の値が返されます。
kotlin
val dayName: String = when (dayOfWeek) {
1 -> {
println("週の始まりです!") // この行は実行される
"月曜日" // この値が返される
}
// ... 他の分岐
else -> {
println("想定外の値です") // この行は実行される
"不明な曜日" // この値が返される
}
}
3.3 when
式(引数なし):より柔軟な条件指定
when
式は、丸括弧 ()
内に評価対象の式を指定しない形でも使用できます。この場合、各分岐の条件部がBoolean
型の式である必要があります。これは、if-else if-else
を連ねる場合と似ていますが、when
の構文を使うことで、より構造的で読みやすくなる場合があります。
構文は以下のようになります。
kotlin
when {
条件式1 -> {
// 条件式1がtrueの場合に実行
}
条件式2 -> {
// 条件式1がfalseで、条件式2がtrueの場合に実行
}
// ... 他の条件
else -> {
// 上記どの条件式もtrueでなかった場合に実行
}
}
この形式のwhen
は、引数ありのwhen
が「ある値がこれらの値のうちどれか?」を判定するのに対し、「これらの条件のうちどれがtrue
か?」を判定するのに適しています。
例を見てみましょう。BMIの値によって判定結果を変えるコードです。
“`kotlin
fun main() {
val bmi = 23.5
when {
bmi < 18.5 -> println("低体重")
bmi < 25 -> println("普通体重") // bmi >= 18.5 && bmi < 25 の場合
bmi < 30 -> println("肥満(1度)") // bmi >= 25 && bmi < 30 の場合
else -> println("肥満(2度以上)") // bmi >= 30 の場合
}
}
“`
この例では、各条件式はBMIの特定の範囲を表しています。when
式は上から順番に条件式を評価し、最初にtrue
になったブロックが実行されます。
この引数なしのwhen
式も、式として値を返すことができます。
“`kotlin
fun main() {
val bmi = 27.8
val bmiResult: String = when {
bmi < 18.5 -> "低体重"
bmi < 25 -> "普通体重"
bmi < 30 -> "肥満(1度)"
else -> "肥満(2度以上)" // 式として使うのでelseは必須
}
println("あなたのBMI区分は $bmiResult です")
}
“`
3.4 when
式の応用例:列挙型(Enum)との組み合わせ
Kotlinの列挙型(Enum class)とwhen
式は非常に相性が良いです。特に、引数ありのwhen
式で列挙型の値を評価する場合、Kotlinコンパイラは全ての列挙値を網羅しているかどうかをチェックしてくれます。もし網羅していない場合、通常はelse
ブロックが必要になりますが、コンパイラが全ての可能性をチェックできたと判断すれば、else
ブロックを省略できる場合があります。
例を見てみましょう。色の列挙型と、それに対応するメッセージを表示するコードです。
“`kotlin
enum class Color {
RED, GREEN, BLUE, YELLOW
}
fun main() {
val color = Color.GREEN
when (color) {
Color.RED -> println("情熱の色")
Color.GREEN -> println("安らぎの色")
Color.BLUE -> println("落ち着きの色")
Color.YELLOW -> println("活力の色")
// この場合、Colorの全ての値を網羅しているのでelseは不要 (式として使う場合も同様)
}
}
“`
もしColor
に新しい列挙値(例:ORANGE
)を追加し、when
式にその値に対する分岐を追加し忘れた場合、コンパイラが警告またはエラーを出すことがあります(特に式として使う場合)。これは、コードの漏れを防ぎ、堅牢性を高めるのに役立ちます。
3.5 when
式の利点と欠点
利点:
* 可読性: 特定の値に対する複数の可能性を分岐させる場合に、if-else if
よりも構造が明確で読みやすいです。
* 表現力: 値の一致、値のリスト、範囲、型判定など、多様な条件指定が可能です。
* 網羅性チェック: 特に列挙型を評価する場合など、コンパイラが全ての可能性を網羅しているかをチェックしてくれる機能は、エラーの早期発見につながります。
* 式としての利用: if
式と同様に、値を返す式として使えるため、簡潔に記述できます。
欠点:
* 冗長性: 単純な真偽値による二者択一の分岐(例:x > 10
かどうか)には、when
式はやや冗長です。このような場合はif
式を使う方がシンプルです。
* 複雑な条件: 各分岐の条件部自体が複雑な論理式になる場合は、引数なしのwhen
よりもif-else if
の方が自然な場合があります。
when
式は、Kotlinで非常に頻繁に利用される構文です。特に、特定の変数や式の値に基づいて処理を切り替えたい場合に、if-else if
よりもスマートで分かりやすいコードを書くことができます。
第4章:Nullableな値と条件分岐 – エルビス演算子 ?:
Kotlinの大きな特徴の一つに、Null安全(Null Safety)があります。変数にnull
を代入できる型(Nullable型)とできない型(Non-nullable型)が厳密に区別されており、これにより実行時エラーの元凶となりがちなNullPointerException(NPE)を多くの場合はコンパイル時に防ぐことができます。
Nullabilityを扱う際には、値がnull
ではない場合に処理を行い、もしnull
だった場合には別の処理を行う、あるいはデフォルト値を提供する、といった条件分岐が必要になります。Kotlinには、このようなNullabilityに関連する条件分岐、特に「Nullableな式がnull
でなければその式の値を使い、null
であればデフォルト値を使う」というケースを簡潔に記述するためのエルビス演算子 (?:
) があります。
このエルビス演算子は、厳密には一般的な意味での「三項演算子」(条件 ? 真の値 : 偽の値
)とは異なります。エルビス演算子は「Nullチェックとデフォルト値の提供」に特化した演算子です。しかし、「値が存在しない(null
である)場合の代替」を指定するという点で、限定的な状況では三項演算子的な使い方ができるため、ここで紹介します。
4.1 エルビス演算子 ?:
の構文と仕組み
エルビス演算子は、Nullableな式の後に記述します。
kotlin
val result = nullableExpression ?: defaultValue
nullableExpression
は、評価結果がNullable型になる式です。?:
がエルビス演算子です。defaultValue
は、nullableExpression
がnull
だった場合に代わりに使用される値です。
この式が評価される際、KotlinはまずnullableExpression
を評価します。
* もしnullableExpression
がnull
ではない場合、その値がresult
に代入されます。defaultValue
は評価されません。
* もしnullableExpression
がnull
である場合、defaultValue
が評価され、その値がresult
に代入されます。
この動きは、他の言語の nullableExpression != null ? nullableExpression : defaultValue
という三項演算子と似ていますね。しかし、KotlinではnullableExpression
が二重に評価されることを防ぎつつ、より短い構文で実現しています。
4.2 エルビス演算子を使った例
ユーザー名を取得する際に、もしユーザー名が設定されていなければ(null
であれば)「ゲスト」というデフォルト名を使いたい、という状況を考えてみましょう。
“`kotlin
fun main() {
val userName: String? = null // NullableなString型で、一旦nullとする
// userNameがnullでなければその値を、nullであれば"ゲスト"を使う
val displayName: String = userName ?: "ゲスト"
println("こんにちは、$displayName さん")
val anotherUser: String? = "Alice" // nullではない場合
val anotherDisplayName: String = anotherUser ?: "ゲスト"
println("こんにちは、$anotherDisplayName さん")
}
“`
このコードを実行すると:
こんにちは、ゲスト さん
こんにちは、Alice さん
となります。最初の例ではuserName
がnull
なので"ゲスト"
が使われ、次の例ではanotherUser
が"Alice"
なのでその値が使われています。
4.3 エルビス演算子の便利な使い方:関数呼び出しや例外スロー
エルビス演算子の右辺(defaultValue
の部分)には、単なる値だけでなく、関数呼び出しや、例外をスローする式などを記述することもできます。
例えば、Nullableな値を処理する際に、もしnull
だったらエラーとして処理を中断したい場合は、return
やthrow
と組み合わせることができます。
“`kotlin
fun processNonNullValue(value: String?) {
// valueがnullであれば、エラーメッセージを表示して関数から抜ける
val nonNullValue: String = value ?: return println(“エラー:値がnullです。”)
// valueがnullでなかった場合のみ、以下の処理が実行される
println("受け取った値は '$nonNullValue' です。処理を続行します。")
}
fun main() {
processNonNullValue(“Hello”) // nullではない場合
processNonNullValue(null) // nullの場合
processNonNullValue(“Kotlin”) // nullではない場合
}
“`
実行結果:
受け取った値は 'Hello' です。処理を続行します。
エラー:値がnullです。
受け取った値は 'Kotlin' です。処理を続行します。
このように、エルビス演算子の右辺にreturn
を書くことで、Nullableな値がnull
の場合に早期に関数を終了させるという、非常にKotlinらしい簡潔な記述が可能です。
また、throw
と組み合わせることもあります。
“`kotlin
fun findUserById(id: Int): String? {
// ダミーの処理:idが1なら”Alice”、それ以外はnullを返すとする
return if (id == 1) “Alice” else null
}
fun getUserNameOrThrow(userId: Int): String {
// findUserByIdの結果がnullならIllegalArgumentExceptionをスロー
val userName: String = findUserById(userId) ?: throw IllegalArgumentException(“User with ID $userId not found”)
return userName // nullでなかった場合はuserNameが返される
}
fun main() {
try {
println(“ユーザーID 1: ${getUserNameOrThrow(1)}”)
println(“ユーザーID 2: ${getUserNameOrThrow(2)}”) // ここで例外が発生
} catch (e: IllegalArgumentException) {
println(e.message)
}
}
“`
実行結果:
ユーザーID 1: Alice
User with ID 2 not found
Nullableな式の結果がnull
の場合に、指定した例外をスローして処理を中断したい場合にも、エルビス演算子は非常に役立ちます。
4.4 エルビス演算子の利点と注意点
利点:
* Null安全: Nullableな値に対して、null
の場合のデフォルト値や代替処理を簡潔に指定できます。
* 簡潔性: Nullチェックとデフォルト値の提供という、頻繁に行われる処理を非常に短い構文で記述できます。
* 読みやすさ: 用途が「Nullチェックとデフォルト値」に特化しているため、その意図がコードから読み取りやすいです。
注意点:
* 用途の限定: エルビス演算子はNullabilityに特化したものです。一般的な「条件 ? 真の値 : 偽の値」のような、Boolean値に基づく二者択一の条件分岐には使用できません。そのような場合はif
式を使います。
* 右辺の評価: エルビス演算子の右辺は、左辺がnull
の場合にのみ評価されます。これは通常の関数呼び出しなどでは問題ありませんが、評価に副作用がある式を使う場合はその挙動を理解しておく必要があります。
エルビス演算子は、Nullableな値を扱う上でKotlinでは欠かせない強力なツールです。Nullチェックとデフォルト値の提供を簡潔に書きたい場面で積極的に活用しましょう。
第5章:その他のKotlinらしい条件分岐関連テクニック
Kotlinには、if
式やwhen
式、エルビス演算子以外にも、条件分岐やプログラムの流れの制御に関連する便利な機能がいくつかあります。これらを理解しておくと、より効率的で読みやすいKotlinコードを書くのに役立ちます。
5.1 早期リターンとラベル付きリターン
関数やループの実行中に、特定の条件が満たされた場合に、それ以降の処理をスキップして関数やループから抜け出したい場合があります。これを「早期リターン」や「早期終了」と呼びます。早期リターンを適切に使うことで、コードのネストを減らし、読みやすさを向上させることができます。
Kotlinでは、return
キーワードを使って早期リターンを実現します。
“`kotlin
fun processUserData(user: User?) {
// userがnullであれば、ここで関数を終了する
if (user == null) {
println(“エラー:ユーザーデータがnullです。処理を中止します。”)
return // ここで関数が終了
}
// userがnullでなかった場合のみ、以下の処理が実行される
println("ユーザーID: ${user.id}")
println("ユーザー名: ${user.name}")
// ... ユーザーデータを処理するコード
}
“`
この例では、関数の冒頭で引数がnull
かどうかをチェックし、もしnull
であればメッセージを表示してすぐにreturn
しています。これにより、後続のユーザーデータを扱うコードは、user
がnull
ではないことが保証された状態で実行されることになります。これは、NullPointerExceptionを防ぐための一般的なパターンであり、if
文とreturn
を組み合わせた典型的な条件による早期終了です。
また、Kotlinではラムダ式を含む高階関数などを使う際に、どのスコープからリターンするかを制御するための「ラベル付きリターン」という機能もあります。しかし、これは初心者には少し応用的なトピックになるため、まずは基本的なreturn
による早期リターンを理解することから始めましょう。ラベル付きリターンに興味がある方は、公式ドキュメントなどを参照してみてください。
5.2 スマートキャスト(Smart Cast)
Kotlinのコンパイラは非常に賢く、ある変数に対して特定の条件を満たすかどうかのチェック(例えば、is
演算子による型チェックや、null
チェック)を行った後、その条件が満たされるブロック内では、その変数をチェックによって保証された型として扱えるようになります。これを「スマートキャスト」と呼びます。
スマートキャストは、明示的な型キャスト(as
)を記述する必要をなくし、コードをより簡潔で読みやすくします。そして、これは条件分岐と密接に関連しています。
例を見てみましょう。Any
型の変数がString
型である場合に、文字列の操作(例:長さを取得)を行いたい場合です。
“`kotlin
fun printLength(obj: Any) {
if (obj is String) {
// objがString型であることがif条件で保証されたので、
// このブロック内ではobjはString型としてスマートキャストされる
println(“文字列の長さ: ${obj.length}”) // obj.length と書ける!
// obj.substring(0, 1) などStringのメソッドがそのまま呼び出せる
} else {
println(“objは文字列ではありません”)
}
}
fun main() {
printLength(“Hello Kotlin”) // 文字列の場合
printLength(123) // 文字列ではない場合
}
“`
実行結果:
文字列の長さ: 12
objは文字列ではありません
このコードでは、if (obj is String)
という条件チェックの後、if
ブロック内ではobj
が自動的にString
型として扱われる(スマートキャストされる)ため、obj.length
のようにString
型のプロパティやメソッドに直接アクセスできます。明示的に(obj as String).length
と書く必要がありません。
同様に、Nullabilityに関するチェックでもスマートキャストは機能します。
“`kotlin
fun greetUser(name: String?) {
if (name != null) {
// nameがnullではないことがif条件で保証されたので、
// このブロック内ではnameはNon-nullable String型としてスマートキャストされる
println(“こんにちは、${name.toUpperCase()}さん”) // name.toUpperCase() と書ける!
// Nullable String型の変数に対して通常は許可されない操作が、このブロック内では可能になる
} else {
println(“名前がありません。”)
}
}
fun main() {
greetUser(“Alice”) // nullではない場合
greetUser(null) // nullの場合
}
“`
実行結果:
こんにちは、ALICEさん
名前がありません。
if (name != null)
という条件チェックのおかげで、if
ブロック内ではname
がNon-nullableなString
型として扱われます。これにより、name.toUpperCase()
のように、Nullable型には通常許されない.
を使った直接アクセスが可能になります。
スマートキャストは、条件分岐と組み合わせてKotlinのコードをより安全かつ簡潔に記述するための非常に重要な機能です。
5.3 デモコード:これらのテクニックを組み合わせる
これまでに紹介したif
式、when
式、エルビス演算子、早期リターン、スマートキャストといったテクニックは、実際のKotlinコードではしばしば組み合わせて使用されます。
例えば、ユーザーの情報を取得し、その状態に応じて適切なメッセージを返す関数を考えてみましょう。
“`kotlin
data class User(val id: Int, val name: String?, val age: Int)
fun getUserStatusMessage(user: User?): String {
// 1. ユーザーデータ自体がnullかチェック(早期リターンとエルビス演算子)
val nonNullUser = user ?: return “エラー:ユーザーデータが見つかりませんでした。”
// nonNullUserはUser型としてスマートキャストされている
// 2. ユーザー名がnullかチェックし、デフォルト名を取得(エルビス演算子)
val displayName = nonNullUser.name ?: "名無しのユーザー"
// 3. ユーザーの年齢に基づいてメッセージを生成(when式とif式)
val ageStatus: String = when (nonNullUser.age) {
in 0..12 -> { // 0歳から12歳の場合(whenの範囲指定)
// if式を使って年齢に応じた具体的なメッセージを生成
if (nonNullUser.age <= 2) "(乳幼児)" else "(子ども)"
}
in 13..19 -> "(ティーンエイジャー)"
in 20..60 -> "(成人)"
else -> "(シニア)" // 60歳より上の場合
}
// 最終的なメッセージを組み立てて返す
return "$displayName さん (ID: ${nonNullUser.id}) $ageStatus"
}
fun main() {
val user1 = User(101, “Alice”, 30)
val user2 = User(102, null, 8)
val user3 = User(103, “Bob”, 75)
val user4: User? = null
println(getUserStatusMessage(user1))
println(getUserStatusMessage(user2))
println(getUserStatusMessage(user3))
println(getUserStatusMessage(user4))
}
“`
実行結果:
Alice さん (ID: 101) (成人)
名無しのユーザー さん (ID: 102) (子ども)
Bob さん (ID: 103) (シニア)
エラー:ユーザーデータが見つかりませんでした。
このコードでは:
* 関数の入り口でエルビス演算子とreturn
を組み合わせてNullチェックと早期リターンを行っています。これにより、以降のコードはuser
がNullではないことを前提に進められます。
* nonNullUser
はUser
型にスマートキャストされています。
* ユーザー名がNullだった場合のデフォルト値取得にエルビス演算子を使っています。
* ユーザーの年齢による分岐にwhen
式を使っています。範囲指定も利用しています。
* when
式の一部の分岐内で、さらにif
式を使ってより詳細な年齢区分メッセージを生成しています。
このように、Kotlinの様々な条件分岐やフロー制御の機能を適切に組み合わせることで、Null安全性を保ちつつ、複雑な条件分岐も分かりやすく、そして簡潔に記述することができます。三項演算子がなくても、あるいはそれ以上に強力なツールがKotlinには用意されていることがお分かりいただけたかと思います。
第6章:なぜKotlinに一般的な三項演算子がないのか?(Kotlinのデザイン思想)
この記事を読んでいる皆さんの中には、他のプログラミング言語、特にJavaやC++などを経験された方がいるかもしれません。それらの言語には、多くの場合、三項演算子(? :
)が存在します。短い条件分岐を1行で書けるため、便利に感じることもあるでしょう。
では、なぜKotlinには、あの一般的な形式の三項演算子が存在しないのでしょうか?これはKotlinが設計される上での思想や目標と深く関わっています。Kotlinの開発チームは、単に他の言語の機能を模倣するのではなく、より良い代替手段を提供することを目指しました。
Kotlinの主な設計目標の一つは、「読みやすく、書きやすく、安全なコード」を書けるようにすることです。三項演算子がないのは、この目標を達成するための設計上の選択の結果です。
考えられる主な理由としては、以下の点が挙げられます。
if
式とwhen
式がその役割を果たす: Kotlinのif
とwhen
は、単なる「文」ではなく、値を返す「式」として利用できます。これにより、他の言語で三項演算子を使っていたような、条件によって値を切り替える処理を、if
式やwhen
式を使って簡潔に記述できます。例えば、val max = if (a > b) a else b
のように書けば、従来の? :
と同等、あるいはそれ以上に読みやすいコードになります。- 可読性の問題: 短い三項演算子は簡潔ですが、ネストしたり、条件や返り値の式が複雑になったりすると、途端に読み解くのが難しくなる傾向があります。Kotlinの
if
式やwhen
式は、三項演算子よりもブロック構造を取りやすいため、複雑な場合でも比較的コードの構造が分かりやすいという利点があります。特にwhen
式は、複数の可能性に対する分岐を非常に分かりやすく記述できます。 - エルビス演算子の存在: NullabilityというKotlinの重要な概念を扱う上で、
null
の場合の代替値を指定する処理は頻繁に発生します。この特定用途のために、Kotlinは?:
というエルビス演算子を用意しました。これは、Nullチェックとデフォルト値という非常に明確な目的を持っており、一般的な三項演算子を使うよりもその意図がコードから伝わりやすいです。
Kotlinの開発者は、一般的な三項演算子を追加することも検討しましたが、既存のif
式、when
式、そしてエルビス演算子が、三項演算子が解決しようとしていた問題を、よりKotlinの哲学に合った形で、かつより柔軟に解決できると判断したのでしょう。
つまり、Kotlinに三項演算子がないことは、機能が不足しているのではなく、より洗練された代替手段が用意されていることの表れなのです。Kotlinのif
式やwhen
式に慣れてくると、きっと「三項演算子がなくても全く困らないどころか、Kotlinの書き方の方が好きだ」と感じるようになるはずです。
第7章:どの方法を選ぶべきか(使い分けのヒント)
ここまで、Kotlinにおける様々な条件分岐の方法を見てきました。if
文、if
式、when
式、エルビス演算子、早期リターンなど、それぞれに得意な状況があります。Kotlin初心者の方がこれらの機能を効果的に使い分けられるように、簡単な指針を示します。
-
最もシンプルな二者択一(真偽値で値を切り替えたい):
- 「もし
A
という条件がtrue
ならX
という値、そうでなければY
という値を使いたい」という場合。 if
式を使うのが最もシンプルでKotlinらしい方法です。- 例:
val result = if (condition) valueX else valueY
- 「もし
-
特定の変数や式の値による多分岐(いくつかの決まった値や範囲):
- 「
number
という変数が1
ならA
、2
ならB
、3
か4
ならC
、それ以外ならD
」のように、ある式の評価結果がいくつかの可能性のどれに一致するかで処理や値を分けたい場合。 when
式(引数あり)を使うのが最も適しています。値のリスト、範囲、型判定なども使えます。- 例:
val result = when (number) { 1 -> valueA; 2 -> valueB; 3, 4 -> valueC; else -> valueD }
- 「
-
複雑な条件や、複数の処理を含む分岐:
- 各分岐で実行したい処理が複数あったり、各分岐の条件式自体が複雑な論理演算を含む場合。
- 値を返す必要がない、またはブロックの最後の値だけが返り値となる場合。
if-else if-else
文 または 引数なしのwhen
式 が適しています。引数なしのwhen
は、複数の独立した条件式を列挙する際にif-else if
よりも構造が分かりやすくなることがあります。- 例 (if文):
kotlin
if (conditionA && conditionB) {
// 複数の処理
} else if (conditionC) {
// 別の複数の処理
} else { ... } - 例 (引数なしwhen式):
kotlin
when {
bmi < 18.5 -> println("低体重")
bmi < 25 -> println("普通体重")
else -> println("肥満")
}
-
Nullableな値が
null
だった場合のデフォルト値/代替処理:- 「
nullableValue
がnull
でなければその値、null
であればdefaultValue
を使いたい」という場合。 - エルビス演算子
?:
を使うのが最も簡潔でKotlinらしい方法です。 - 例:
val result = nullableValue ?: defaultValue
null
だった場合に早期リターンや例外スローをしたい場合もエルビス演算子が便利です。- 例:
val nonNullValue = nullableValue ?: return
- 例:
val nonNullValue = nullableValue ?: throw Exception(...)
- 「
-
関数の途中で特定の条件の場合に終了したい:
- 関数の引数が無効な場合、あるいは特定の条件が満たされた場合に、後続の処理を実行せずにその関数を抜けたい場合。
if
文とreturn
を組み合わせた早期リターンが一般的です。- 例:
if (inputData == null) { return }
これらの指針はあくまで一般的なものです。最も大切なのは、書いているコードの可読性を高く保つことです。もしある書き方が他の書き方よりも少し短くなるとしても、それが他の開発者(あるいは未来の自分自身)にとって理解しにくいものであれば、より冗長でも分かりやすい書き方を選ぶべきです。
Kotlinの強力な機能に慣れてくると、自然とどの状況でどの構文を使うのが最適かが分かってくるはずです。たくさんのコードを読んで、書いて、試してみてください。
第8章:実践的なヒントと注意点
Kotlinで条件分岐を記述する際に、より良いコードを書くための実践的なヒントと注意点をいくつか紹介します。
- 可読性を最優先する: 最も重要なのは、コードが他の人(そして未来の自分)にとって読みやすく理解しやすいこと。短さだけを追求して、複雑な
if
式やwhen
式を書くのは避けましょう。必要であれば複数行に分けたり、一時変数を使ったりすることを躊躇しない。 -
複雑な条件は分解する:
if (conditionA && (conditionB || conditionC) && !conditionD)
のように、非常に複雑な条件式は、可読性を著しく低下させます。このような場合は、条件の一部を変数に抽出したり、関数に切り出したりすることで、コードが追いやすくなります。
“`kotlin
// 悪い例
if (user != null && user.isActive && (user.role == Role.ADMIN || user.permissions.contains(Permission.EDIT))) {
// …
}// 良い例
val userExists = user != null
val userIsActive = user?.isActive == true // Nullable safetyに注意
val isAdmin = user?.role == Role.ADMIN
val canEdit = user?.permissions?.contains(Permission.EDIT) == trueif (userExists && userIsActive && (isAdmin || canEdit)) {
// …
}
または、条件自体を関数にする。
kotlin
fun User?.canEdit(): Boolean {
return this != null && this.isActive && (this.role == Role.ADMIN || this.permissions.contains(Permission.EDIT))
}if (user.canEdit()) {
// …
}
* **マジックナンバーやマジックストリングを避ける:** 条件式や分岐の結果として使う定数や文字列は、直接リテラル値として書くのではなく、定数や列挙型として定義すると、コードの意図が明確になり、変更にも強くなります。
kotlin
// 悪い例
when (statusCode) {
200 -> println(“OK”)
404 -> println(“Not Found”)
500 -> println(“Internal Server Error”)
// statusCodeが何を意味しているか、200, 404, 500が何を指すか分かりにくい場合がある
}// 良い例 (定数やenumを使う)
const val STATUS_OK = 200
const val STATUS_NOT_FOUND = 404
// …
when (statusCode) {
STATUS_OK -> println(“OK”)
STATUS_NOT_FOUND -> println(“Not Found”)
// … 定義を見れば意味が分かる
}// あるいは列挙型
enum class HttpStatus(val code: Int) { OK(200), NOT_FOUND(404), / … / }
// …
when (httpStatus) { // httpStatusはHttpStatus型
HttpStatus.OK -> println(“OK”)
HttpStatus.NOT_FOUND -> println(“Not Found”)
// when式がHttpStatusの全てのenumを網羅しているかチェックしてくれる
}
* **早期リターンを活用してネストを減らす:** 関数の最初の方でエラー条件や前提条件をチェックし、該当する場合は早期に`return`することで、後続のメイン処理のネストを減らし、コードを左揃えに保つことができます。これは「ガード句(Guard Clause)」と呼ばれるテクニックです。
kotlin
// 悪い例 (ネストが深い)
fun processData(data: Data?) {
if (data != null) {
if (data.isValid) {
// 処理A
if (data.hasPermission) {
// 処理B
// メイン処理
} else {
// 権限エラー処理
}
} else {
// データ無効エラー処理
}
} else {
// データnullエラー処理
}
}// 良い例 (早期リターンでネストを減らす)
fun processData(data: Data?) {
if (data == null) {
println(“データnullエラー”)
return
}
if (!data.isValid) {
println(“データ無効エラー”)
return
}
if (!data.hasPermission) {
println(“権限エラー”)
return
}// 前提条件が満たされた状態でのメイン処理 // 処理A // 処理B
}
``
?
* **Nullable safetyとスマートキャストを理解する:** KotlinのNull安全な設計は、条件分岐と深く結びついています。(セーフコール)、
?:(エルビス演算子)、
!!(非Nullアサーション)、そして
if (variable != null)や
if (variable is Type)といった条件チェックの後のスマートキャストの仕組みをしっかり理解することが、安全で簡潔なコードを書く上で不可欠です。
println`を使って途中の変数や条件式の値を出力するのも有効なデバッグ手段です。
* **デバッグを活用する:** 条件分岐が期待通りに動作しない場合は、デバッガーを使ってコードの実行をステップ実行し、各条件式がどのように評価されているか、どのブロックが実行されているかを確認しましょう。
これらのヒントを意識することで、Kotlinでの条件分岐がより効果的になり、堅牢でメンテナンスしやすいコードを書けるようになるでしょう。
まとめ:Kotlinの条件分岐は三項演算子なしでもシンプルで強力!
この記事では、Kotlin初心者の方に向けて、一般的な三項演算子を使わずにシンプルに条件分岐を記述する方法を詳しく解説しました。
重要なポイントをおさらいしましょう。
- Kotlinには、JavaやC++のような
? :
形式の三項演算子は存在しません。 - その代わりに、Kotlinの
if
文は式(Expression)として値を返すことができます。これにより、val result = if (condition) value1 else value2
のように、三項演算子と同等、あるいはそれ以上に簡潔かつ強力に、条件によって値を切り替える処理を記述できます。これが三項演算子の最も一般的なユースケースの代替となります。 - 複数の条件に基づいて処理や値を分けたい場合は、
when
式が非常に強力です。特定の値との一致だけでなく、値のリスト、範囲、型判定なども条件として指定できます。when
式も式として値を返すことができます。複雑な多分岐にはif-else if-else
よりもwhen
式の方が適している場合が多いです。 - Nullableな値に対して、
null
の場合のデフォルト値を指定したり、null
であれば処理を中断したりする場合には、エルビス演算子 (?:
) が非常に便利です。これはNull安全に特化した機能であり、限定的な三項演算子のような使い方ができます。 - 関数の冒頭などで、特定の条件を満たさない場合にそれ以降の処理をスキップするには、
if
文とreturn
を組み合わせた早期リターンが有効です。これによりコードのネストを減らし、可読性を向上させることができます。 - 条件分岐と組み合わせて、Kotlinのスマートキャスト機能も活用できます。型チェックやNullチェックを行った後、そのブロック内では変数が適切な型に自動的にキャストされるため、安全かつ簡潔にその型のメンバにアクセスできます。
Kotlinが三項演算子を採用しなかったのは、これらの代替手段、特に強力なif
式やwhen
式によって、三項演算子の利便性を維持しつつ、その欠点(特に可読性)を克服し、よりKotlinらしい安全で表現豊かなコードを書けるようにするためです。
最初はこれらの新しい書き方に少し戸惑うかもしれませんが、慣れてくるとそのシンプルさと強力さに気づくはずです。たくさんのコードを書き、読み、試行錯誤する中で、それぞれの機能がどのような状況で最も輝くのかを感覚として掴んでいきましょう。
Kotlinでの条件分岐は、プログラムの論理を構築する上で非常に重要な要素です。この記事で学んだ様々な方法をマスターして、あなたのKotlinコーディングライフをより楽しく、そして効率的なものにしてください!
これで、Kotlinでの条件分岐に関する基本的な内容は網羅されました。さらに深く学びたい場合は、Kotlinの公式ドキュメントや、より実践的なコーディング例を探してみることをお勧めします。
Happy Coding!