今回はKotlinの条件分岐「if」の基本構文と省略構文、ifで使われる条件式についてお話します。
ifの基本構文
まずは汎用的に使えるifの基本構文をチェックしておきましょう。
if
if(結果がtrue/falseになる式){
式がtrueのときの処理
}
ifの後の()
内では、その結果がtrueなのかfalseなのかの判定が行われます。結果がtrueのときは処理が実行され、falseだと何も起こりません。
()内の結果が異なる2つのifを比較してみます。
fun main() {
if(1 > 0){ //「1は0より大きい?」の結果がtrue
println("正の数")
}
if(1 < 0){ //「1は0より小さい?」の結果がfalse
println("負の数")
}
}
//正の数
上のコードでは()内の結果がtrueと判定された上のifのみ、処理が実行されています。
if – else
では次に()内の結果がfalseの場合でも、何らかの処理が実行されるようにしてみましょう。「そうでなければ」を示すelseを追加することで、()内の結果によって処理を2つに分岐させます。
fun main() {
if(-1 > 0){ //-1は0より大きい?
println("正の数")
}else{
println("負の数")
}
}
//負の数
このifの()内の結果はfalseです。elseがある場合、()内がfalseであればelse内に記述された処理が実行されます。
if – else if – else
次に複数のifをつなげて、分岐を3つに増やしてみます。この場合はelse if(〇〇)
で、「そうでなくて〇〇なら」を表現します。
fun main() {
//変数numは-1から1までのランダムな整数
val num = (-1..1).shuffled().first()
if(num == 0){ //numが0なら...
println("numは0")
}else if(num == 1){ //そうでなくてnumが1なら...
println("numは1")
}else{ //上が全てfalseなら...
println("numは-1")
}
}
//numは1
実行結果はランダムに選ばれた変数numの値によって毎回変化します。else if
は複数設定することができるので、いくつもの分岐を設定することが可能です。
最後のelseは「それ以外なら」を表すので、条件式は必要ありません。()を記述しないということに注意してください。
Kotlinのifは式である
Kotlinのifはただの文ではなく、それ自体が「式」です。式であるということは、その結果が1つの値として成立し、それを変数に代入したりすることができます。
上の例を使って、ifの結果を変数に代入してみましょう。
fun main() {
val num = (-1..1).shuffled().first()
//ifの結果をString型の変数ansに代入
val ans: String = if(num == 0){
//println()ではなく、String型を返すように変更
"numは0"
}else if(num == 1){
"numは1"
}else{
"numは-1"
}
println(ans)
}
//numは0
if式ではelseが必須
この場合、変数ansはString型です。if
のみでは条件式がfalseのとき、戻り値無しとなってしまいます。
式として利用する場合は最低でもelse
が必須であり、基本的にその結果は全て同じ型でなければなりません。
ただし例外をスローする、あるいはNothing型を返すなら話は別です。
//Nothing型を返す関数
fun fail(): Nothing{
throw Exception("不正な数値です")
}
fun main() {
val num = (-1..1).shuffled().first()
val ans: String = if(num == 0){
"numは0"
}else if(num == 1){
"numは1"
}else{
//else節でNothing型を返す
fail()
}
println(ans)
}
ifの省略構文
記述方法
ifは波括弧{}を省いた省略構文を使うこともできます。
if(式) 式がtrueのときの処理 else 式がfalseのときの処理
最初の例を省略構文で書き直してみましょう。
fun main() {
//if単体
if(1 > 0) println("正の数")
//if-else
if(1 < 0) println("正の数") else println("負の数")
}
//正の数
//負の数
それぞれ波括弧{}が省略され、1行で簡潔に記述することができました。
ただ3つ以上の分岐があるif-else if-else
で省略構文を使用してしまうと、逆に可読性が落ちてしまう場合も多いので注意してください。
//if-else if-else
if(1 > 0) println("正の数") else if(1 == 0) println("0") else println("負の数")
Kotlinには三項演算子が無い
Kotlinはこの省略構文によって、Javaの三項演算子の処理を表現しています。そのため、以下のような「?」と「:」を使った三項演算子は存在しません。
//Javaのコード。そのままではKotlinでは動きません
//1 > 0がtrueならコロン:の左辺、falseなら右辺が変数ansに代入される
String ans = 1 > 0 ? "正の数" : "負の数";
条件式に入る式
ここまではifの構文を見てきましたが、ifの()に入る式とはどのようなものでしょうか? 代表的なものを見ていきます。
比較演算子
上の例でも使用した演算子。左辺と右辺の値を比較します。
演算子 | 意味 |
---|---|
== | 左右が同じ値かどうか |
!= | 左右が異なる値かどうか |
=== | 左右が参照するものが同じかどうか |
!== | 左右が参照するものが異なるかどうか |
> | 左の方が大きいかどうか |
< | 右の方が大きいかどうか |
>= | 左の方が大きいか、もしくは同じかどうか |
<= | 左の方が小さいか、もしくは同じかどうか |
論理演算子
さらに複雑な条件を指定するような場合、上記の比較演算子に加えて「〇〇で、しかも✕✕」や「〇〇か、もしくは✕✕」などを表現する論理演算子があります。
演算子 | 意味 |
---|---|
&& | 論理積(AND) 「左辺右辺ともにtrueならtrue」 |
|| | 論理和(OR) 「左辺か右辺どちらか、もしくは両方がtrueならtrue」 |
xor | 排他的論理和 「左辺と右辺どちらかがtrueのときのみtrue」 |
! | 論理否定(NOT) 「true / falseを逆転させる」 |
is / in演算子
指定した型かどうかを調べるis
、指定した値がそこに含まれるかどうかを調べるin
演算子。
fun main() {
val str = "わっしょい"
if(str is String) println(str)
}
//わっしょい
fun main() {
val menu = listOf("ワイン","ハイボール","サングラス")
if("サングラス" in menu) println("あるよ")
}
//あるよ
その他のメソッド
最終的にBooleanを返すメソッドであれば使用可能です。こちらではほんの一例を掲載しておきます。
val str = "abc"
//要素が空かどうかを調べるisEmpty
if(str.isEmpty()) println("空です") else println(str) //abc
//正規表現にマッチするかどうかを調べるmatches
val str = "abcdees"
if(str.matches("""abc.*""".toRegex())) println("マッチ!")
//マッチ!
//指定した文字で始まる(終わる)かどうかを調べるstartsWithやendsWith
val str = "その他のメソッド"
if(str.endsWith('ト')) println("OK") else println("NG") //NG
数値や文字列そのままは不可
val x = 1
if(x) println(true)
//エラー: Type mismatch: inferred type is Int but Boolean was expected
数値や文字列そのままではtrue/falseとみなされず、エラーとなります。上のようなコードが通用する言語もあるので、若干注意が必要です。
比較演算子/論理演算子の使用例
最後に比較演算子や論理演算子を使ったいくつかの例を挙げてみましょう。
この例では女子側が結婚相手に求める条件をifで表現します。まずは論理演算子を使わなかった場合どうなるか?という例です。
fun main() {
var income = 2000 //プロポーズする男性のスペック
var height = 183
var count = 2
if(income>=1000){ //女子側の返答の条件 年収いくら以上
if(height>=180){ //年収が上回った場合、身長はこれ以上
println("はい")
}
}else{
println("ごめんなさい")
}
}
//はい
上の例では比較演算子だけを使い、ANDはifのネスト(入れ子)で表現しています。
条件が少ない場合はネストも選択肢に入りますが、条件が多くなればなるほど入れ子の階層が多くなってしまい、読み書きするのが大変になってしまいます。そこで論理演算子を使って、こう書き直してみましょう。
fun main() {
var income = 2000
var height = 183
var count = 2
if(income>=1000 && height>=180){ //&&を使って条件の記述を簡略化
println("はい")
}else{
println("ごめんなさい")
}
}
//はい
記述方法が違うだけでコードの内容は同じですが、女子側の条件が1行に収まり、可読性が向上したのが分かると思います。
条件は論理積が使われています。ということは、
fun main() {
var income = 900 //年収が下がるとダメ
var height = 183
var count = 2
if(income>=1000 && height>=180){
println("はい")
}else{
println("ごめんなさい")
}
}
//ごめんなさい
男性の年収が下がってしまう、もしくは身長が180cm未満になると論理積の条件を満たすことができず、答えは「ごめんなさい」に変化します。
さらに条件を追加してみましょう。
fun main() {
var income = 2000
var height = 183
var count = 2
if(income>=1000 && height>=180 && count<2){
println("はい")
}else{
println("ごめんなさい")
}
}
//ごめんなさい
過去の浮気実績(count)が2未満であるという条件を女子側が付け足してくると、年収と身長がいくら高かろうが過去の浮気歴が引っかかってしまい、答えは「ごめんなさい」となります。
&&
の場合、左辺も右辺も全ての条件が満たされなければtrueになりません。しかし、
fun main() {
var income = 800
var height = 175
var count = 20
val name="Masaki Suda"
if(name=="Masaki Suda" || income>=1000 && height>=180 && count<2){
println("はい")
}else{
println("ごめんなさい")
}
}
//はい
菅田将暉であれば他は何でも良いという条件が加わった場合、菅田将暉がプロポーズした場合は年収がいくらであろうが浮気を何回していようが100%「はい」です。