見出し画像

猫では分からないKotlinのapply関数

Kotlinには、スコープ関数にapply関数が存在します。
apply関数を使用することで、以下のように、インスタンスを生成しつつ、初期値を代入し、ログを出力するといったようなことを適切なスコープ内で実施することが可能になっています。

User().apply { 
  age=10 
  name="Yamada"  
  logger.info(this) 
}

applyスコープ関数の定義

そこで、apply関数がどのような定義がされているのかを解析してみました。
以下がその定義です。

@kotlin.internal.InlineOnly
public inline fun <T> T.apply(block: T.() -> Unit): T {
   contract {
       callsInPlace(block, InvocationKind.EXACTLY_ONCE)
   }
   block()
   return this
}

何ということでしょうか

・関数の引数であるblockの定義が、T.() -> Unitになっています。
・つまり、blockは関数リテラルで定義し、リテラル内には引数をとってはならず返り値の型はなし(Unit)でなければならないというのです。
・しかもT.()となっており、レシーバを使えと?でもレシーバは、T.applyのところの話であって、引数のところに関係ないのではと思ってしまいます。

実に難しい。しかも、スコープ関数はapply以外にも、let、with、run、alsoがあるというのです。使い方が分かったとしても、自らスコープ関数を作る領域までには達することができません。これでは猫に教えたときに猫パンチを喰らいますので、頑張って勉強していきます。

この記事が気に入ったらサポートをしてみませんか?