7

ライブラリ (具体的にはcom.twitter.finagle.mdns.MDNSResolver) からクラスを取得しました。クラスを拡張したい (Try[Group] ではなく、Future[Set] を返すようにしたい)。

もちろん、サブクラス化してそこにメソッドを追加できることはわかっています。しかし、私は Scala を学びながら学んでおり、これは何か新しいことに挑戦する機会のように思えます。

これが可能であると私が考える理由は、の動作ですJavaConverters。次のコード:

class Test {
    var lst:Buffer[Nothing] = (new java.util.ArrayList()).asScala
}

asScalaJava の にはメソッドがないため、コンパイルされませんArrayList。しかし、いくつかの新しい定義をインポートすると:

class Test {
    import collection.JavaConverters._
    var lst:Buffer[Nothing] = (new java.util.ArrayList()).asScala
}

それから突然方法ありasScalaます。ArrayListクラスが透過的に拡張されているように見えます。

の動作をJavaConverters正しく理解していますか? その方法論を複製できますか (また複製する必要がありますか)?

4

3 に答える 3

12

Scala は、暗黙的な変換と呼ばれるものをサポートしています。以下を見てください。

val x: Int = 1
val y: String = x

2 番目の割り当ては機能しませStringInt。ただし、次をスコープに追加すると(スコープ内にのみ、どこからでも来ることができます)、機能します:

implicit def int2String(x: Int): String = "asdf"

メソッドの名前は重要ではないことに注意してください。

したがって、通常行われることは pimp-my-library-pattern と呼ばれます:

class BetterFoo(x: Foo) {
  def coolMethod() = { ... }
}

implicit def foo2Better(x: Foo) = new BetterFoo(x)

これにより、 を呼び出すことができcoolMethodますFoo。これは非常に頻繁に使用されるため、Scala 2.10 以降では次のように記述できます。

implicit class BetterFoo(x: Foo) {
  def coolMethod() = { ... }
}

これは同じことを行いますが、明らかに短くて優れています。

したがって、次のことができます。

implicit class MyMDNSResolver(x: com.twitter.finagle.mdns.MDNSResolver) = {
  def awesomeMethod = { ... }
}

また、スコープ内にある場合は、awesomeMethod任意のを呼び出すことができます。MDNSResolverMyMDNSResolver

于 2013-06-12T18:11:00.167 に答える