公開日:2020/02/01更新日:2020/08/03
【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は使用できなくなるので注意が必要です。
- 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な変数に対して、安全にアクセスすることができます。
- 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
- ブロック処理内では、レシーバーをthisで参照できる
- ブロック処理の最後の値を返す(レシーバーでなくてもよい)
詳しい解説はこちらをご覧ください。
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
- ブロック処理内では、レシーバーをitで参照できる
- ブロック処理の最後の値を返す(レシーバーでなくてもよい)
詳しい解説はこちらをご覧ください。
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才です。
- ブロック処理内では、レシーバーをthisで参照できる
- レシーバー自身を返す
詳しい解説はこちらをご覧ください。
まとめ
- alsoは、オブジェクトにまとめて処理を行う際に便利
- ?. をセーフコール演算子と呼ぶ
- ?.also { }で、nullでないことを確認し、安全に処理を行うことができる
- alsoを呼び出すオブジェクトをレシーバーと呼ぶ
- ブロック{ }内では、itでレシーバーを参照できる
- itではなく、任意の変数でレシーバーを参照することもできる
- alsoはブロック処理後、レシーバー自身を返す
関連記事