Kotlinのラムダ式について

採用はこちら

Kotlinのラムダ式は、単なる「コードを短く書くための記法」ではありません。

関数を値として扱うという考え方を、実務で安全かつ直感的に使えるよう設計された、Kotlinの中核機能です。

本記事では、構文 → 型推論 → 高階関数 → it → returnの挙動 → inlineとの関係 → 実務での使い分けまでを、誤解が生じやすいポイントを中心に整理します。

目次

ラムダ式とは何か

ラムダ式とは、名前を持たない関数(無名関数)を値として扱う仕組みです。

Kotlinでは、次のことが自然にできます。

  • 関数を変数に代入する
  • 関数を引数として渡す
  • 関数を戻り値として返す

これにより、処理の流れを細かく書くよりも「どのような処理を適用するか」を明確に表現できるようになります。

ラムダ式の基本構文

基本形

{ 引数 -> 処理 }

例:数値を2倍にするラムダ

val double = { x: Int -> x * 2 }

呼び出しは通常の関数と同じです。

double(5) // 10

関数型と型推論

Kotlinでは、関数も明確な「型」を持ちます。

明示的に型を書く場合

val sum: (Int, Int) -> Int = { a, b -> a + b }

これは「Intを2つ受け取り、Intを返す関数」という意味です。

実務で多い書き方(型推論)

val sum = { a: Int, b: Int -> a + b }

Kotlinの型推論が十分に働くため、冗長になりません。

引数が1つの場合の it

ラムダの引数が 1つだけ で、かつ 引数名を明示しない場合、暗黙の引数 it が使えます。

val square = { it * it }

これは次と等価です。

val square = { x: Int -> x * x }

コレクション操作では特に多用されます。

listOf(1, 2, 3).map { it * 2 }

ラムダの戻り値ルール

  • 最後の式が戻り値になる
  • 原則として return は使わない
val isEven = { x: Int ->
    x % 2 == 0
}

この場合、Boolean が返ります。

高階関数とラムダ

高階関数とは

次のいずれかを満たす関数です。

  • 関数を引数として受け取る
  • 関数を戻り値として返す

例:処理を引数として受け取る

fun calculate(
    a: Int,
    b: Int,
    operation: (Int, Int) -> Int
): Int {
    return operation(a, b)
}

呼び出し側

calculate(5, 3) { x, y -> x + y }

ラムダを最後の引数に書けるルール

Kotlinでは、最後の引数がラムダの場合() の外に書くことができます。

calculate(5, 3) { x, y -> x * y }

このルールが、KotlinのDSL的な書き味を支えています。

スコープ関数とラムダ

let

text?.let { it.length }
  • it:対象オブジェクト
  • 戻り値:ラムダの結果

apply

val user = User().apply {
    name = "Taro"
    age = 20
}
  • this:対象オブジェクト
  • 戻り値:オブジェクト自身

ラムダと無名関数の違い

ラムダ式

val f = { x: Int -> x * 2 }
  • return は原則使えない
  • シンプルな処理向き

無名関数

val f = fun(x: Int): Int {
    return x * 2
}
  • return が使える
  • 制御が複雑な処理向き
  • return常にその無名関数自身からのローカルreturn

ラムダと return の正確なルール

基本原則

  • ラムダの中では通常 return は書けない
  • 書けるのは以下の2種類のみ

ラベル付き return(ローカル)

list.forEach {
    if (it == 2) return@forEach
}
  • ラムダ(forEachに渡した処理)から抜けるだけ
  • 外側の関数は継続する

非ローカルreturn(条件付き)

次の条件をすべて満たす場合に限り、ラムダ内の return外側の関数を終了 します。

  • ラムダが inline 関数に渡されている
  • crossinline で制限されていない
  • ラムダがその場で実行される(保持・遅延実行されない)

代表例:forEach

fun test() {
    listOf(1, 2, 3).forEach {
        if (it == 2) return
    }
    println("ここは実行されない")
}

なぜ forEach だけ挙動が違うのか

  • forEachinline 関数
  • ラムダが呼び出し元に展開される
  • そのため return が「外側の関数」に効く

逆に、crossinline が付いている場合や、ラムダが後で実行される設計では非ローカルreturnは使えません。

実務での使いどころ

  • コレクション操作(map / filter / fold)
  • 非同期・コールバック処理
  • UIイベント処理
  • 設定・初期化DSL
  • 処理の差し替えによる柔軟な設計

まとめ

Kotlinのラムダ式は、

  • 関数を「値」として安全に扱える
  • 可読性と表現力を両立できる
  • API設計・DSL設計の基盤になる

という点で、Kotlinらしいコードを書くための必須知識です。

特にreturn・inline・ラベル付きreturnの理解は、中級者と初心者を分ける重要な境界線になります。

以上、Kotlinのラムダ式についてでした。

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

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