Scope functionsは非常に便利ですが,Kotlinの関数定義を理解していなかったため,慣れるまで何度もネットで検索して使い方を思い出してと非常に時間がかかってしまいました.ここで理解しようと思って理解したことをまとめます.使い方については色んなサイトでまとめられているのでそちらに譲ります.
なお,今回使用する単語へのKotlinの公式サイトへのリファレンスはページ最下部にまとめています.
Scope function
let
public inline fun <T, R> T.let(block: (T) -> R): R
- inline
inline関数は関数オブジェクトをインスタンスとして持たず,コンパイル時にコードに埋め込むことで呼び出し時のオーバーヘッドを低減できる機能です.(逆にinline関数が長すぎる場合はcompile後のコードが長くなる背反はある)
- <T, R>
Genericsの宣言です.2つの任意の型を使用する関数であることを表します
- T.let
拡張関数(extension function)でletを定義しています.拡張関数はあるクラスに対して,そのクラス外から追加で関数を定義できる機能です.例えば,third partyのクラスに何か関数を追加したい場合の利用が想定されています.
Tに対して関数を定義し,かつ,publicであるので,このパッケージ(kotlin)をimportしている限り任意の型に対してこの関数を適用することが可能です.kotlinは通常暗黙的なimportなのであらゆる箇所で使用可能です
- T.let (block: (T) -> R): R
letの詳細定義です.引数は関数型(lambda)で,返り値はblockの実行結果であるRを返します. ここでblockの引数として単一引数(T)を与えていますので,block内では暗黙的にitでアクセス可能です.it以外の名前を付けることも勿論可能です.
なお,with, run等と比較してreceiver typeではないので,T (Context Object)へのアクセスを省略することはできず,常にit.xxxxのようにアクセスします.
str.let {
println(it.uppercase())
}
str.let{ string ->
println(string.uppercase())
}
run
//1
public inline fun <R> run(block: () -> R): R
//2
public inline fun <T, R> T.run(block: T.() -> R): R
1はただの関数です.
2は拡張関数で,letに追加して新しい部分は以下です.
- block: T.() -> R
T.()はreceiver objectとしてTを取り,引数はなしということを表します.receiver objectを取ることでblock内ではthisでアクセス可能,すなわち,省略可能になります.
str.run {
println(uppercase()) //abbreviation
println(this.uppercase()) //does the same
}
with
public inline fun <T, R> with(receiver: T, block: T.() -> R): R
以降は特に新しいことはありません.強いてあげれば,withを記載する場合よく以下のような使い方をしますが,これはtrailing lambdaという機能が使用されています.引数の最後のlambda,すなわち今回の場合はblockは関数呼び出しの後に{}で処理を記載してよいことになっています.
with(str){
str.uppercase()
}
apply
public inline fun <T> T.apply(block: T.() -> Unit): T
apply, alsoは返り値がTです.
also
public inline fun <T> T.also(block: (T) -> Unit): T
公式サイト Reference
Scope Functionsの効果的な使用方法
Scope functions | Kotlin
extension function (拡張関数)とは
Extensions | Kotlin
it (lambdaにおいて,引数が一つの時に暗黙的に命名される引数名)
Higher-order functions and lambdas | Kotlin
receiver typeとは
Higher-order functions and lambdas | Kotlin
inlineとは
Inline functions | Kotlin
trailing lambda
Higher-order functions and lambdas | Kotlin