Kotlinのalsoについて

採用はこちら

Kotlinには「スコープ関数(Scope Functions)」と呼ばれる便利な関数群があります。

代表的なものとして次の5つがあります。

  • let
  • run
  • with
  • apply
  • also

この中で also は、

対象オブジェクトをラムダ式に「引数」として渡し、その後に元のオブジェクト自身を返す関数

という特徴を持つスコープ関数です。

主に ログ出力・デバッグ・追加処理などの副作用を挟みたい場合 に使用されます。

目次

alsoの基本構文

also の基本構文は次のようになります。

object.also { it ->
    // ここで処理
}

多くの場合、引数名は省略されて it が使われます。

object.also {
    println(it)
}

alsoの動作

処理の流れは次のようになります。

  1. object をラムダに渡す
  2. ラムダの処理を実行
  3. 元の object をそのまま返す

つまり 値は変わらず、その途中に処理だけを挟めるのが特徴です。

alsoの基本例

次の例は、オブジェクト生成後にログを出力するケースです。

data class User(val name: String)

fun main() {
    val user = User("Taro")
        .also {
            println("ユーザー作成: ${it.name}")
        }

    println(user)
}

実行結果

ユーザー作成: Taro
User(name=Taro)

このコードでは

  • also のラムダ内では itUser オブジェクト
  • also の戻り値は User

になります。

つまり 処理を追加してもオブジェクト自体は変化しません。

メソッドチェーンでの利用

also はメソッドチェーンの途中に処理を挟む用途でよく使われます。

val result = listOf(1,2,3)
    .also { println("元データ: $it") }
    .map { it * 2 }
    .also { println("2倍後: $it") }

出力

元データ: [1, 2, 3]
2倍後: [2, 4, 6]

このように also を使うことで、

  • データ処理の途中
  • 値の状態
  • 計算結果

を確認できます。

そのため デバッグ用途でよく利用されます。

alsoの代表的な用途

ログ出力

val user = getUser()
    .also { println("取得ユーザー: $it") }

デバッグ

val result = calculate()
    .also { println("計算結果: $it") }

オブジェクト生成後の処理

val file = File("test.txt")
    .also { println("作成したファイル: ${it.path}") }

バリデーション

val age = inputAge()
    .also {
        require(it >= 0) { "年齢は0以上である必要があります" }
    }

alsoの仕組み(概念)

also の動作は概念的には次のように理解できます。

inline fun <T> T.also(block: (T) -> Unit): T {
    block(this)
    return this
}

つまり

  1. 対象オブジェクトをラムダに渡す
  2. ラムダを実行する
  3. 元のオブジェクトを返す

という仕組みです。

applyとの違い

alsoapply は非常に似ています。

どちらも 元のオブジェクトを返す スコープ関数です。

ただし、オブジェクトの参照方法が異なります。

関数参照方法戻り値主な用途
also引数 it元オブジェクト追加処理・ログ
applyレシーバ this元オブジェクトオブジェクト設定

alsoの例

val user = User("Taro")
    .also { println(it.name) }

applyの例

val user = User("Taro").apply {
    println(name)
}

違い

  • also → オブジェクトは it
  • apply → オブジェクトは this

そのため

  • 設定処理 → apply
  • 副作用処理 → also

と使い分けることが多いです。

letとの違い

alsolet は戻り値が異なります。

関数戻り値
also元オブジェクト
letラムダの結果

also

val result = "Hello"
    .also { println(it) }

戻り値

Hello

let

val result = "Hello"
    .let { it.length }

戻り値

5

つまり

  • also → 値を維持
  • let → 値を変換

という違いがあります。

null安全とalso

Kotlinでは ?.also と組み合わせることで、nullでない場合のみ処理を実行できます。

user?.also {
    println("ユーザー存在: $it")
}

usernull の場合、ラムダは実行されません。

alsoを使うときの注意点

also は便利ですが、多用するとコードの可読性が下がる可能性があります。

特に次のような場合は注意が必要です。

  • スコープ関数を多重にネストする
  • 副作用の強い処理を大量に書く
  • it が何を指しているか分かりにくい

適切に使えばコードが読みやすくなりますが、使いすぎは逆効果になる場合があります。

まとめ

also は Kotlinのスコープ関数の一つで、次の特徴を持っています。

主な特徴

  • オブジェクトを 引数 it としてラムダに渡す
  • ラムダの後に 元のオブジェクトを返す
  • ログやデバッグなどの 副作用処理に向いている

主な用途

  • ログ出力
  • デバッグ
  • バリデーション
  • メソッドチェーン途中の処理

他のスコープ関数との違い

  • also → オブジェクト維持
  • apply → オブジェクト設定
  • let → 値変換

以上、Kotlinのalsoについてでした。

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

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