[Android]Kotlinスコープ関数のざっくり過ぎる解説①(applyとalso)

Kotlinには、処理のブロック内({ }のこと)でスコープを変えることによって、簡潔な記述が出来る便利なスコープ関数が、標準関数として用意されています。

ただ、便利な半面ちょいややこしいという面もあります。

そこで、よく使うと思われる「apply と also」を、本当にざっくり過ぎる感じで解説してみました。

 

本当にざっくり過ぎるまとめはこれ

スコープ関数はそもそも標準関数なので、使いみちは色々考えられるかと思うのですが、本当にざっくり言うと、「apply」と「also」はオブジェクトの(複雑な)初期化や設定をするときに使えると思っておけばいいのではないかと。

 

違いは「this」と「it」

関数の定義で見てみると

applyはこれ

/**
 * Calls the specified function [block] with `this` value as its receiver and returns `this` value.
 */
@kotlin.internal.InlineOnly
public inline fun <T> T.apply(block: T.() -> Unit): T { ← applyは処理対象Tをレシーバーとして受け取っている
    contract {
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    block()
    return this
}

 

alsoはこれ

/**
 * Calls the specified function [block] with `this` value as its argument and returns `this` value.
 */
@kotlin.internal.InlineOnly
@SinceKotlin("1.1")
public inline fun <T> T.also(block: (T) -> Unit): T { ← alsoは処理対象をラムダ式の引数(it)として受け取っている
    contract {
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    block(this)
    return this
}

 

どちらも、「this」をブロック内で処理してその結果を返すという点では同じですが、

「apply」の場合は処理対象をレシーバーとして受け取り、

「also」の場合はラムダ式の引数(it)として受け取る点が違うようです。

「also」は「apply」より後に産まれたらしいのですが、ブロック内外で「this」が変わってしまう「apply」の代替として考え出されたのでしょうか。

 

例はこんな感じ

なので、実際に例を見てみると、違いは処理対象の受け取り方(呼び出し元へのアクセスの仕方)だけです。

もともとこんなコードは

val intent = Intent(this@WordListActivity, EditActivity::class.java)
intent.putExtra(getString(R.string.intent_key_question), strSelectedQuestion)
intent.putExtra(getString(R.string.intent_key_answer), strSelectedAnswer)

 

こんな感じになります。

applyの方は、処理対象である「Intent」をレシーバーの「this」としてアクセスしており、この「this」は省略できるので「putExtra」の前には何もいらなくなる。その代わりブロック内外で「this」の意味合いが変わってしまう。

一方、alsoの方は純粋なラムダ式なので、処理対象である「Intent」はその唯一の引数「it」として受け取っているため、「putExtra」の前に「it」が必要になる。その代わりブロック内外で「this」の意味合いは同じまま。

 

とはいえ、Kotlinを作った天才の方々にはいろんな思惑があるかと思いますが、apply・alsoとも結局は処理対象の自分自身を返すわけなので、そうであれば、オブジェクトの初期化に関しては、より簡潔に記述できる「apply」で良いのではないかと、凡人の私は思ったりするわけであります。

(詳しくは下の動画で解説していますので、よろしければご覧ください)

アバター

北川 博之(きーぼー)

みんなのプログラミング by Telulu LLC代表 大阪府生まれ。京都大学経済学部経済学科卒業。 2000年より、日本生命保険、ニッセイアセットマネジメント、パトナム・インベストメンツ(米国)で、日本株トレーダー・アナリスト、経営企画、システム開発等の業務に従事。主に日本株の売買執行・投資分析、経営計画の策定、海外投資家向け日本株営業、社内トレーディングシステム及び経理システムの開発等を行う。 2016年、合同会社てるる設立。スマホアプリプログラマーとして「新感覚脳トレアプリ・記憶戦隊オボエルンジャー」「Meisoー1番シンプルなマインドフルネス瞑想アプリ」をはじめとした、メンタルヘルス・知育系アプリを中心に4タイトル・計8本(Android・iOS)をリリース。 2017年、自身のこれまでの社会人経験・プログラミング経験・子育て経験を基に、プログラミングを通じて人々の人生を豊かにして、未来に希望の持てる明るい社会の実現に貢献したいとの想いから、プログラミング完全初心者と挫折経験のある人を支援する「プログラミング挫折撲滅プロジェクト・みんなのプログラミング by Telulu LLC」を設立し、プログラミングサポーター活動と心理カウンセリング活動を開始。これまでに3,000名を超える方のプログラミング挫折撲滅をサポート。

こんな記事も読まれています

みんプロにかける想い

  1. プログラミングは手段の1つに過ぎない(目的は自分のアイデアを形にすること)

  2. プログラミングはみんなのもの!(プログラミングの醍醐味である「楽しさ」を伝えたい)

  3. こんな無駄な苦労をするのはぼくで最後にしたい(ぼくがプログラミング講座をはじめたわけ)

  4. プログラミングを通じて「やわらかい世の中」を作りたい(ぼくがプログラミング講座をやっている本当の理由②)

  5. ぼくが別に言う必要のない挫折の黒歴史をあえてさらけ出している理由(自分の中にある「ブロック」を外すきっかけにしてほしい)

みんプロ作成アプリ




みんプロ代表の黒歴史


TOP