LoginSignup
2
0

メンバー拡張メソッド

Posted at

メンバー拡張メソッドの宣言

Kotlinでは、拡張メソッドを定義することができる。
通常はトップレベルに配置するが、実は拡張メソッドをメンバーとして定義することもできる。

interface Monoid<M> {
  val identity: M
  fun compose(a: M, b: M)

  // Extension method as a member!
  fun List<M>.fold(): M = fold(identity, this@Monoid::compose)
}

そこそこKotlinを使っていたけど、この前初めて知った。

2つのレシーバー

拡張メソッドをメンバーとして定義すると、本来のインスタンスを指すthisと、拡張メソッドのレシーバーを指すthisの2つが存在することになる。これをDispatch receiver, Extension receiverと呼び分ける。

通常Extension receiverが優先的に呼び出されるが、Qualified this構文を使うことでDispatch receiverを明示的に指定することができる。

interface Monoid<M> {
  val identity: M
  fun compose(a: M, b: M)

  fun List<M>.fold(): M =
    this.fold(             // List::fold
      this.identity,       // Monoid::identity
      this@Monoid::compose // Monoid::compose
    )
}

メンバー拡張メソッドの呼び出し

呼び出すときはwithを使うのが便利だ。

object MonoidString : Monoid<String> {
  override val identity: String = ""
  override fun compose(a: String, b: String): String = a + b
}

fun main() {
  with (MonoidString) {
    println(listOf("Hello", " ", "World").fold())
  }
}

ScalaのImplicit parametersみたいで面白い。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0