Genta Hirauchi

最終更新日:2020/02/01

【Kotlin基礎】スコープ関数alsoの実装方法と用途を解説

  • alsoの実装方法が知りたい。
  • alsoはどんな時に使うと便利なの?
  • also以外のスコープ関数について知りたい。

こんにちは、元太です。

Kotlinにはスコープ関数という覚えておくと便利な関数があります。

スコープ関数にはいくつか種類があるのですが、本記事では、スコープ関数alsoに焦点を当て解説致します。

他のスコープ関数につきましては、簡単な解説と、詳細をまとめた記事へのリンクがありますので、そちらをご覧頂けたらと思います。

目次

スコープ関数alsoの実装方法と用途について

alsoの基本的な使い方

スコープ関数alsoは、公式ドキュメントで以下のように定義されております。

  • Kotlin
inline fun  T.also(block: (T) -> Unit): T

【公式ドキュメント】 : also – Kotlin Programming Language

公式ドキュメントの説明文には、「Calls the specified function block with this value as its argument and returns this value.(この値を引数として指定された関数ブロックを呼び出し、この値を返します。)」と記されています。

もう少しイメージしやすい形にすると、以下のようになります。

  • Kotlin
結果 = レシーバー.also {
   // 処理
}

レシーバーにはオブジェクトが入ります。説明文の「この値」というのが、このレシーバーに該当します。

説明文の「関数ブロック」というのは、alsoの後の { // 処理 } の部分に該当します。
また、関数ブロック{ }内では、レシーバーをitで呼び出すことができます。

そして、「この値を返します」とあるように、レシーバーを返却します。

まだalsoがどのような処理を行うのか良くわからないと思いますので、実際の処理の流れをサンプルコードで見ていきましょう。

  • Kotlin
class User {
   var name: String = ""
   var age: Int = 0
}

val result = User().also {
   it.name = "伊藤"
   it.age = 30
}

println("私は${result.name}、${result.age}で

// "私は伊藤、30才です。

User()でUserクラスのインスタンスを生成すると同時に、alsoでUserのパラメータに値を代入しております。

itは、ブロック処理後にレシーバー自身を返すので、変数resultには、パラメータに値が代入されたUserが格納されることになります。

ブロック{ }内では、レシーバーは暗黙的にitで参照できますが、任意の変数で参照することもできます。

  • Kotlin
val result = User().also { user ->
   user.name = "伊藤"
   user.age = 30
}

userという変数でレシーバーを参照するように変更しました。
このようにレシーバーを参照する変数を明示した場合は、itは使用できなくなるので注意が必要です。

Point
  • alsoを呼び出すオブジェクトをレシーバーと呼ぶ
  • ブロック{ }内では、itでレシーバーを参照できる
  • itではなく、任意の変数でレシーバーを参照することもできる
  • alsoはブロック処理後、レシーバー自身を返す

alsoの具体的な使用用途

alsoは、オブジェクトに対してまとめて処理を行う場合に使うと便利です。

■ コードで動的にViewを実装する

  • also使用
  • also未使用
findViewById(R.id.container).also {
   it.orientation = LinearLayout.VERTICAL

   val textView = TextView(this).also {
       it.text = "テキストが入ります。"
       it.textSize = 18f
       it.textAlignment = TextView.TEXT_ALIGNMENT_CENTER
   }

   it.addView(textView)
}
val container = findViewById(R.id.container)
container.orientation = LinearLayout.VERTICAL

val textView = TextView(this)
textView.text = "テキストが入ります。"
textView.textSize = 18f
textView.textAlignment = TextView.TEXT_ALIGNMENT_CENTER

container.addView(textView)

alsoを使用した方が、各Viewのまとまりや親子関係がわかりやすいですね。

またalsoには、nullチェックをした上で、安全にオブジェクトにアクセスすることができるという利点もあります。

■ nullチェックをした上で、処理を行う

  • Kotlin
val nullTextView: TextView? = null

nullTextView?.also {
   it.text = "テキストが入ります。"
   it.textSize = 18f
   it.textAlignment = TextView.TEXT_ALIGNMENT_CENTER
}

nullTextViewは、nullです。
このnullTextViewに対し、「?.」というものが付いています。これはセーフコール演算子と呼ばれるもので、変数がnullでなければ変数にアクセスするという役割を持っています。

このセーフコール演算子とalsoを組み合わせることで、Nullableな変数に対して、安全にアクセスすることができます。

Point
  • alsoは、オブジェクトにまとめて処理を行う際に便利
  • ?. をセーフコール演算子と呼ぶ
  • ?.also { }で、nullでないことを確認し、安全に処理を行うことができる

also以外のスコープ関数について

also以外のスコープ関数について簡単な解説と、詳しい内容をまとめた記事へのリンクを紹介致します。

runについて

runは、公式ドキュメントで以下のように定義されております。

  • Kotlin
inline fun  run(block: () -> R): R

inline fun  T.run(block: T.() -> R): R

【公式ドキュメント】 : run – Kotlin Programming Language

【使用例】

  • Kotlin
val number = 10
val result = number.run {
   this + 10
}
println(result)

// 20
Point
  • ブロック処理内では、レシーバーをthisで参照できる
  • ブロック処理の最後の値を返す(レシーバーでなくてもよい)

詳しい解説はこちらをご覧ください。

【Kotlin基礎】スコープ関数runの実装方法と用途を解説

Kotlinには、スコープ関数というシンプルですが、覚えておくと便利な関数があります。本記事では、runというスコープ関数について解説致します。

letについて

letは、公式ドキュメントで以下のように定義されております。

  • Kotlin
inline fun  T.let(block: (T) -> R): R

【公式ドキュメント】 : let – Kotlin Programming Language

【使用例】

  • Kotlin
val str = "hello"
val result = str.let {
   it.length
}

println(result)

// 5
Point
  • ブロック処理内では、レシーバーをitで参照できる
  • ブロック処理の最後の値を返す(レシーバーでなくてもよい)

詳しい解説はこちらをご覧ください。

【Kotlin基礎】スコープ関数letの実装方法と用途を解説

本記事では、スコープ関数letについて詳しく解説しております。letはNullチェックを行う際に便利な関数でス。是非皆さんも、この記事を読んで、letを使いこなせるようになっていただけたらと思います。

applyについて

applyは、公式ドキュメントで以下のように定義されております。

  • Kotlin
inline fun  T.apply(block: T.() -> Unit): T

【公式ドキュメント】 : apply – Kotlin Programming Language

【使用例】

  • Kotlin
class User {
   var name: String = ""
   var age: Int = 0
}

val result = User().apply {
   name = "田中"
   age = 20
}

println("私の名前は${result.name}です、${result.age}才です。")

// "私の名前は田中です、20才です。
Point
  • ブロック処理内では、レシーバーをthisで参照できる
  • レシーバー自身を返す

詳しい解説はこちらをご覧ください。

【Kotlin基礎】スコープ関数applyの実装方法と用途を解説

スコープ関数は、初めはなかなか理解しづらいかもしれませんが、覚えておくととても便利です。そこで本記事では、スコープ関数applyについて解説致します。applyは、個人的に最も使用頻度の高い関数です。

まとめ

  • alsoは、オブジェクトにまとめて処理を行う際に便利
  • ?. をセーフコール演算子と呼ぶ
  • ?.also { }で、nullでないことを確認し、安全に処理を行うことができる
  • alsoを呼び出すオブジェクトをレシーバーと呼ぶ
  • ブロック{ }内では、itでレシーバーを参照できる
  • itではなく、任意の変数でレシーバーを参照することもできる
  • alsoはブロック処理後、レシーバー自身を返す