takeIf は、条件を満たした場合のみそのオブジェクトを返し、条件を満たさない場合は null を返す関数です。
簡単に言うと、
条件が true → 元のオブジェクトを返す
条件が false → null を返す
という動作をします。
定義は次のようになっています。
public inline fun <T> T.takeIf(predicate: (T) -> Boolean): T?
ポイントは次の通りです。
- レシーバーオブジェクトに対して条件判定を行う
- 条件を満たした場合だけそのオブジェクトを返す
- 条件を満たさない場合は
null - 戻り値は Nullable型(T?)
基本的な使い方
もっともシンプルな例を見てみます。
val number = 10
val result = number.takeIf { it > 5 }
println(result)
結果
10
理由は、条件 10 > 5 が true だからです。
そのため、元の値 10 がそのまま返されます。
次に条件を満たさない場合です。
val number = 3
val result = number.takeIf { it > 5 }
println(result)
結果
null
条件が false のため、null が返ります。
if文との関係
takeIf は、次の if 文と同じ意味になります。
通常の書き方
val result = if (number > 5) number else null
takeIfを使った書き方
val result = number.takeIf { it > 5 }
このように、値を条件付きで返す処理を簡潔に書けるのが takeIf の特徴です。
ただし、条件によって 別の値を返したい場合 は if 文の方が自然です。
例
val result = if (number > 5) "OK" else "NG"
このような場合に takeIf を使うのはあまり適していません。
実装イメージ
takeIf の内部動作はとてもシンプルです。
概念的には次のような実装になっています。
inline fun <T> T.takeIf(predicate: (T) -> Boolean): T? {
return if (predicate(this)) this else null
}
つまり、
predicateに現在のオブジェクトを渡す- 結果が
trueならthisを返す falseならnullを返す
という処理です。
takeIf と let の組み合わせ
takeIf は let と組み合わせて使われることが多いです。
val number = 10
number
.takeIf { it > 5 }
?.let {
println("条件を満たしました: $it")
}
処理の流れ
takeIfで条件判定- 条件が true なら値が返る
?.letにより nullでない場合のみ処理が実行される
もし条件が false の場合は、
takeIf → null
となるため、let は実行されません。
実務でよくある使い方
値の範囲チェック
val validScore = score.takeIf { it in 0..100 }
0〜100の範囲に入っている場合のみ値を保持します。
文字列が空でない場合だけ使用
val text = input.takeIf { it.isNotBlank() }
空文字や空白文字列の場合は null になります。
ファイル存在チェック
val file = File("data.txt")
val validFile = file.takeIf { it.exists() }
存在するファイルだけを取得できます。
takeUnless との違い
Kotlinには takeIf と対になる関数として takeUnless があります。
takeIf
条件 true → 値を返す
条件 false → null
takeUnless
条件 true → null
条件 false → 値を返す
例
val number = 3
val result = number.takeUnless { it > 5 }
println(result)
結果
3
条件が true の場合は null になり、false の場合は値が返されます。
takeIf を使うときの注意点
値の生成自体は防げない
次のようなコードには注意が必要です。
val result = createExpensiveObject().takeIf { it.isValid() }
この場合、isValid() が false でも
createExpensiveObject()
は 先に実行されます。
つまり takeIf は
条件を満たすときだけ生成する
関数ではありません。
あくまで
すでにある値を条件で残すかどうか判断する
関数です。
単純な条件分岐では if の方が読みやすいこともある
例えば次のコードです。
user.takeIf { it.age >= 20 }
?.drinkBeer()
これは文法的には正しいですが、次のコードの方が読みやすいと感じる場合も多いです。
if (user.age >= 20) {
user.drinkBeer()
}
takeIf は便利ですが、すべての条件分岐を置き換えるものではありません。
takeIf を使うべき場面
takeIf が特に役立つのは次のようなケースです。
- 値を条件付きで残したい
- null安全と組み合わせたい
- メソッドチェーンの途中で条件を入れたい
例
val result =
input
.trim()
.takeIf { it.isNotEmpty() }
?.uppercase()
このように 処理チェーンの中に条件を自然に組み込めるのが takeIf の大きな利点です。
まとめ
takeIf は、オブジェクトに条件を適用し、
条件 true → 元の値を返す
条件 false → null
という動作をする関数です。
主な特徴
if (condition) value else nullを簡潔に書けるletなどと組み合わせて null安全な処理を書ける- 処理チェーンの途中に条件を入れられる
ただし、
- 値の生成自体を抑制するわけではない
- 単純な条件分岐では
ifの方が読みやすいこともある
という点には注意が必要です。
以上、Kotlinのtakeifについてでした。
最後までお読みいただき、ありがとうございました。










