11
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Kotlinスコープ関数(let,run,also,apply)の使い方について考えてみる

Last updated at Posted at 2022-09-21

はじめに

Kotlinの標準ライブラリにはスコープ関数という関数が存在します。
自分自身、JavaからKotlinに入ったのでそれなりの文法などはすんなりと理解できたのですが、スコープ関数についてはJavaには無いので理解が薄いままなんとなくで使用していました。
今回理解を深めるために少し調べてみたので備忘録を含めまとめたいと思います。

5つのスコープ関数

Kotlinには5つのスコープ関数が用意されています。

  • let
  • apply
  • run
  • also
  • with

これらの関数は、基本的に全て同じことを行いますが、それぞれ特徴がありますのでまとめます。
(withに関してはほとんど使用機会がありません(自分は)ので今回は割愛させていただきます。)

let

まずは使用頻度の高いlet

スコープ関数名 対象オブジェクト 戻り値
let it 最後の実行コード
    val foo: Int? = 3
    val hoge = foo?.let { it * 2 } ?: 0
    println("hoge : $hoge")

letは主にnullableな変数に対して使用する事が多く、nullチェックをスマートに記述することができます。

hoge : 6

fooがnullではない場合letスコープ内の処理が行われます( it * 2 )
fooがnullの場合エルビス演算子に処理が移り0が返ります。

従来のコード
    val foo: Int? = 3
    val hoge =
        if (foo != null) {
            foo * 2
        } else {
            0
        }

よくあるnullをif文でチェックして処理を分岐する簡単なコード。

スコープ関数使用
    val foo: Int? = 3
    val hoge = foo?.let { foo -> 
        foo * 2
    } ?: 0

スコープ関数を用いて記述するとこのようにスッキリ書けます。

    val foo: Int? = 3
    val hoge = foo?.let { foo ->
        foo * 10000
        foo * 20000
        foo * 0 // ←これが戻り値
    }
    print("hoge : $hoge")

冒頭でも説明したようにletではletスコープ内で最後に評価した値が戻り値として返ります。

hoge : 0

letスコープ内でfooの値をどんだけ書き換えても最後の行の値が返されているのがわかります。

run

runはletと似ています.

スコープ関数名 対象オブジェクト 戻り値
run this 最後の実行コード

runletの違いは対象オブジェクトをthisで参照できる点です。また、Kotlinではthisは省略可能ですのでより簡潔に記述することが可能です。

    val hoge = foo?.run {
        toString() // this.toString()
    }

also

スコープ関数名 対象オブジェクト 戻り値
also it 対象オブジェクト

alsoletrunと違い戻り値が対象オブジェクト自身です。
一つのオブジェクトに対してまとめて処理を実行した場合などに便利です。(AndroidだとViewの初期化処理等)

従来のコード
                     // ↓これが戻り値
        val testText = binding.testText
        testText.text = data.peekContent()
        testText.setOnClickListener{ } // クリック処理        
スコープ関数使用
                     // ↓これが戻り値
        val testText = binding.testText.also { 
            it.text = data.peekContent()
            it.setOnClickListener { } // クリック処理 
        }

apply

スコープ関数名 対象オブジェクト 戻り値
apply this 対象オブジェクト

applyalsoの対象オブジェクトがthisバージョンといった感じです。

従来のコード
    val intent = Intent(this, SubActivity::class.java)
    intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY	)
    intent.addCategory("test")
    startActivity(intent)

同じ記述(intent)が続くので無駄感がある。

スコープ関数使用
    Intent(this, SubActivity::class.java).apply {
        addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY	)
        addCategory("test")
        startActivity(this)
    }

スコープ関数を使用することでスッキリ書くことができます。
applyは対象のオブジェクト自身が戻り値になるので、 startActivity(this) と記述します。

さいごに

Kotlinのスコープ関数についてまとめてみました。
実務ではまだ上手く使用できていませんが、便利に活用できたらなと思います。
また、スコープ関数の便利な使い方などあればコメント頂けると幸いです!!

ではまたっ!!

11
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?