Kotlinのlet、run、also、apply、with

このチュートリアルでは、Kotlinで利用可能な重要な標準ライブラリ関数のいくつかを実装します。 kotlin-stdlibは、私たちに有用な高階関数を提供し、慣用的なパターンを実装します。これらがKotlinでのプログラミングをより簡単かつ高速にする方法を見ていきます。以下で説明する関数は次のとおりです:

  • let
  • run
  • also
  • apply
  • with

Kotlin let

letは、それが呼び出されたオブジェクトをパラメータとして取り、ラムダ式の結果を返します。 Kotlin letは、スコープ関数であり、式内で宣言された変数は外部で使用できません。 Kotlin let関数を示す例を以下に示します。

fun main(args: Array) {
    var str = "Hello World"
    str.let { println("$it!!") }
    println(str)

}
//Prints
//こんにちは世界!!
//こんにちは世界

itキーワードには、let内のプロパティのコピーが含まれます。 letからの最後の値が引数として返されます。

var strLength = str.let { "$it function".length }
println("strLength is $strLength") //prints strLength is 25

let関数のチェーン

var a = 1
var b= 2

a = a.let { it + 2 }.let { val i = it + b
        i}
println(a) //5

見ての通り、iをローカル変数として宣言しました。2番目のlet関数の最後の文をiに設定すると、そのプロパティを外部プロパティaに戻します。

ネストしたlet

次のように、let式を別のlet式の内部に設定できます。

var x = "Anupam"
x.let { outer -> outer.let { inner -> print("Inner is $inner and outer is $outer") } }

//Prints
//内部はAnupamで、外部もAnupamです。

ネストされたletでは、itキーワードを使用できません。両方のlet関数でitに明示的な名前を割り当てる必要があります。以下に、最も外側のletのみが値を返す様子が示されています。

var x = "Anupam"
    x = x.let { outer ->
        outer.let { inner ->
            println("Inner is $inner and outer is $outer")
            "Kotlin Tutorials Inner let"
        }
        "Kotlin Tutorials Outer let" 
    }
    println(x) //prints Kotlin Tutorials Outer let

nullチェックのためのlet

さらに、letは次のようにNull可能なプロパティをチェックするのに便利です。

var name : String? = "Kotlin let null check"
name?.let { println(it) } //prints Kotlin let null check
name = null
name?.let { println(it) } //nothing happens

let式内のコードは、プロパティがnullでない場合にのみ実行されます。したがって、letはif elseのnullチェッカーからも私たちを救ってくれます!

Kotlin実行

Kotlinのrunは別の興味深い機能です。次の例はその使用例を示しています。

var tutorial = "This is Kotlin Tutorial"
    println(tutorial) //This is Kotlin Tutorial
    tutorial = run {
        val tutorial = "This is run function"
        tutorial
    }
    println(tutorial) //This is run function

Kotlinのrun式は外部のプロパティを変更することができます。したがって、上記のコードでは、ローカルスコープでそれを再定義しました。

  • let関数と同様に、run関数も最後のステートメントを返します。
  • letとは異なり、run関数はitキーワードをサポートしていません。

letとrun

letとrun関数を組み合わせてみましょう。

var p : String? = null
    p?.let { println("p is $p") } ?: run { println("p was null. Setting default value to: ")
        p = "Kotlin"}

    println(p)
//Prints
//pがnullでした。デフォルト値を設定しています: 
//Kotlin

Kotlinも

その名前が示すように、also式は呼び出されたオブジェクトに追加の処理を行います。letとは異なり、新しい返り値ではなく元のオブジェクトを返します。したがって、返り値は常に同じ型です。letと同様に、alsoitを使用します。

var m = 1
m = m.also { it + 1 }.also { it + 1 }
println(m) //prints 1 

Kotlinのletとalsoの違い

次のコードスニペットは、letalsoの違いを明確に示しています。

data class Person(var name: String, var tutorial : String)
var person = Person("Anupam", "Kotlin")

var l = person.let { it.tutorial = "Android" }
var al = person.also { it.tutorial = "Android" }
    
println(l)
println(al)
println(person)

上記のコードでは、Dataクラスを使用しました。also式はデータクラスオブジェクトを返しますが、let式は何も返しません(Unit)(明示的に何も指定していないため)。

Kotlinのapply

Kotlinのapplyは、型に対する拡張関数です。オブジェクト参照(レシーバーとも呼ばれます)で式を実行し、完了時にオブジェクト参照を返します。

data class Person(var name: String, var tutorial : String)
var person = Person("Anupam", "Kotlin")

person.apply { this.tutorial = "Swift" }
println(person)

applyとalsoの違い

data class Person(var n: String, var t : String)
var person = Person("Anupam", "Kotlin")

person.apply { t = "Swift" }
println(person)

person.also { it.t = "Kotlin" }
println(person)

注意: applyではitは許可されていません。データクラスのプロパティ名が関数内で一意であれば、thisを省略できます。thisを隠したくない場合にのみalsoを使用する必要があります。

Kotlinで

applyのように、withは参照を毎回呼び出す必要なしにインスタンスのプロパティを変更するために使用されます。

data class Person(var name: String, var tutorial : String)
var person = Person("Anupam", "Kotlin")

with(person)
    {
        name = "No Name"
        tutorial = "Kotlin tutorials"
    }

再び、withはいくつかの違いを除いてapplyに類似しています。

Kotlinのapplyとwithの比較

  • withはオブジェクト(レシーバー)なしで実行され、一方、applyにはオブジェクトが必要です。
  • applyはオブジェクト参照で実行されますが、withは単に引数として渡されます。
  • with関数の最後の式は結果を返します。
var xyz = with(person)
    {
        name = "No Name"
        tutorial = "Kotlin tutorials"
        val xyz = "End of tutorial"
        xyz
    }
    println(xyz) //End of tutorial

これで、関数内で変数を変更したりオブジェクトを変更するためのKotlin標準関数については以上です。

Source:
https://www.digitalocean.com/community/tutorials/kotlin-let-run-also-apply-with