7

我有一个图书馆的课程(特别是,com.twitter.finagle.mdns.MDNSResolver)。我想扩展这个类(我希望它返回一个 Future[Set],而不是一个 Try[Group])。

当然,我知道我可以对它进行子类化并在那里添加我的方法。但是,我正在努力学习 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

第二个分配不起作用,因为String是预期的,但Int找到了。但是,如果您将以下内容添加到范围内(只是在范围内,可以来自任何地方),它会起作用:

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 回答
2

做到这一点的方法是使用隐式转换。这些可用于定义视图,它们用于丰富现有库的用途称为“ pimp my library ”。

我不确定您是否需要编写 from Try[Group]to的转换Future[Set],或者您可以编写一个 from TrytoFuture和另一个 from Groupto Set,然后让它们编写。

于 2013-06-12T18:06:42.133 回答
2

这是使用隐式转换实现的;此功能允许您在调用无法识别的方法时自动将一种类型转换为另一种类型。

在 Martin Odersky 在 2006 年写的一篇文章之后,您特别描述的模式被称为“丰富我的图书馆”。它仍然是您想要做的一个很好的介绍:http ://www.artima.com/weblogs /viewpost.jsp?thread=179766

于 2013-06-12T18:07:15.623 回答