UGA Boxxx

つぶやきの延長のつもりで、知ったこと思ったこと書いてます

【Kotlin】スコープ関数 with と run の違い

Kotlinを勉強していて、 withrunが書き方は違うものの行う処理が似ていると思い、使い分けがわからなかったので調べた

withの特徴

  • レシーバオブジェクト: ブロック内でthisとして扱われる
  • 戻り値: ラムダ式の結果が返される
  • 呼び出し方: with(オブジェクト) { ... } の形式で呼び出す

withは、主にオブジェクトに対して複数の操作を行いたいが、その結果を返す必要がある場合に使用する

例: withの使い方

val person = Person("John", 30)

val result = with(person) {
    println(name)   // `this`は`person`なので、`name`や`age`に直接アクセスできる
    println(age)
    age + 10  // 最後の式の値が戻り値になる
}

println(result)  // 出力: 40

この例では、withを使ってpersonのプロパティにアクセスし、age + 10の結果が戻り値として返されている

runの特徴

  • レシーバオブジェクト: ブロック内でthisとして扱われる
  • 戻り値: ラムダ式の結果が返される
  • 呼び出し方:
    • レシーバとして呼び出し: オブジェクト.run { ... }
    • 非レシーバとして呼び出し: run { ... }(単にコードブロックを実行するために使う)

runは、あるオブジェクトに対して処理を行い、その処理結果を返したいときや、または単にブロック内で複雑なロジックを実行したいときに使う

例: runの使い方

val person = Person("John", 30)

val result = person.run {
    println(name)  // `this`は`person`
    println(age)
    age + 10
}

println(result)  // 出力: 40

withとほとんど同じように動作しているが、runpersonに対して直接呼び出されている違いがある

withrunの違い

  • 呼び出し方法:

    • withwith(オブジェクト)として呼び出す
    • runオブジェクト.run { ... }の形式で呼び出す。もしくは、オブジェクトがない場合でもrun { ... }の形式で使える
  • 目的:

    • withは通常、オブジェクトに対する操作をまとめて実行し、その結果を返すために使う
    • runは、オブジェクトに対して直接呼び出して処理を行うか、もしくはブロック内で単独の処理を行うときに使う

使い分け

オブジェクトに対して複数の操作をまとめたい場合はwithを使う: 特にオブジェクトに対する一連の操作を明示的に書きたい場合

  with(file) {
      println(name)
      println(size)
  }

オブジェクト自体に操作を行いたい場合はrunを使う: オブジェクトに直接処理をしたいときや、ブロックの結果をすぐに使いたい場合

  val length = string.run {
      println(this)
      length
  }