言語
日本語
English

Caution

お使いのブラウザはJavaScriptが無効になっております。
当サイトでは検索などの処理にJavaScriptを使用しています。
より快適にご利用頂くため、JavaScriptを有効にしたうえで当サイトを閲覧することをお勧めいたします。

Kotlin辞典

  1. トップページ
  2. Kotlin辞典
  3. apply

apply

対応: Kotlin 1.0(2016)

Kotlinのスコープ関数『apply』は、オブジェクトを設定・初期化するときに使います。ブロック内では『this』でオブジェクトを参照でき、戻り値はレシーバー自身です。

構文

// apply の基本形
val result = オブジェクト.apply {
    // this = オブジェクト
    プロパティ = 値
    メソッド()
}
// result はオブジェクト自身

構文一覧

スコープ関数コンテキスト参照戻り値用途
apply { }this(省略可)レシーバー自身オブジェクトの設定・初期化に使います。
also { }itレシーバー自身副作用(ログ・デバッグ)の挿入に使います。
let { }itラムダの結果null チェックや変換チェーンに使います。
run { }this(省略可)ラムダの結果オブジェクトのセットアップと計算を組み合わせます。

サンプルコード

sample_scope_apply.kt
data class Person(var name: String = "", var age: Int = 0, var email: String = "")

fun main() {
    // apply でオブジェクトを初期化します(this は省略可)
    val person = Person().apply {
        name = "綾波レイ"
        age = 14
        email = "ayanami_rei@wp-p.info"
    }
    println(person)
    // Person(name=綾波レイ, age=14, email=ayanami_rei@wp-p.info)

    // StringBuilder の構築にもよく使われます
    val sb = StringBuilder().apply {
        append("Hello")
        append(", ")
        append("Kotlin!")
    }
    println(sb.toString()) // Hello, Kotlin!

    // apply チェーン — 複数の設定をつなげられます
    val list = mutableListOf<String>().apply {
        add("Apple")
        add("Banana")
        add("Cherry")
    }
    println(list) // [Apple, Banana, Cherry]

    // apply は自身を返すため、そのまま別のメソッドを呼べます
    val size = mutableListOf<Int>().apply {
        addAll(listOf(1, 2, 3, 4, 5))
    }.size
    println(size) // 5
}
scope_apply.kt
kotlinc scope_apply.kt -include-runtime -d scope_apply.jar
java -jar scope_apply.jar
Person(name=綾波レイ, age=14, email=ayanami_rei@wp-p.info)
Hello, Kotlin!
[Apple, Banana, Cherry]
5

よくあるミス

NG例1: apply の戻り値はレシーバー自身です — ブロックの最後の式は返されません

NG例2: apply のブロック内では it ではなく this でオブジェクトを参照します

NG例3: val プロパティを持つイミュータブルなオブジェクトに apply を使っても再代入できません

data class Character(var name: String = "", var age: Int = 0)

fun main() {
    // apply のブロックの最後の式は戻り値にならない(Character 自身が返る)
    val wrongResult = Character().apply {
        name = "碇シンジ"
        name // この値は返らない
    }
    println(wrongResult.name) // 碇シンジ(Character が返っている)
}

ブロックの最後の式を返したいときは run を使います

sample_scope_apply_mistakes.kt
data class Character(var name: String = "", var age: Int = 0, var series: String = "")

fun main() {
    // run なら最後の式が戻り値になる
    val shinjiName = Character().run {
        name = "碇シンジ"
        name
    }
    println(shinjiName) // 碇シンジ

    // apply のブロック内は this でアクセスする(プロパティ名を直接書ける)
    val rei = Character().apply {
        name = "綾波レイ"
        age = 14
        series = "エヴァンゲリオン"
    }
    println(rei) // Character(name=綾波レイ, age=14, series=エヴァンゲリオン)
}

コンパイルして実行すると次のようになります。

kotlinc sample_scope_apply_mistakes.kt -include-runtime -d sample_scope_apply_mistakes.jar
java -jar sample_scope_apply_mistakes.jar
碇シンジ
Character(name=綾波レイ, age=14, series=エヴァンゲリオン)

概要

『apply』はオブジェクトの初期化ブロックとしてよく使われます。ブロック内では『this』でレシーバーを参照するため、プロパティ名だけで直接代入できます。

戻り値がレシーバー自身のため、生成したオブジェクトをそのまま変数に代入したり、メソッドチェーンの一部として使うのに便利です。

副作用の挿入にはalsoを、null チェックにはletを、計算結果を返したいときはrun / withを参照してください。

記事の間違いや著作権の侵害等ございましたらお手数ですがまでご連絡頂ければ幸いです。