0

免责声明:我从 C# 来到 Scala,我非常欣赏 LINQ。因此,我立即对迭代器和序列感到宾至如归。我错过了产量“C#风格”,但我能够用延续来自己做饭……即使它会付出性能损失。

现在,当我在 C# 中遗漏某些方法而不是集合时,我只是将其定义为扩展方法,并且编译器在有效处理代码方面做得非常好。在 Scala 中,我使用Pimp丰富我的库方法,但我有点担心性能。

然而,与我的“产量迭代器”相反,这是一种公认​​的常见模式。Scala 编译器是否对其进行了优化,删除了临时对象的创建?

class RichFoo(f: Foo) {
  def baz = f.bar()
  def baz2 = f.bar() * 2
}
object RichFoo {
  implicit def foo2Rich(f: Foo) = new RichFoo(f)
}

// on the caller side
val f : Foo = ....
f.baz
f.baz2
// this translates, literally, to new RichFoo(f).baz, new RichFoo(f).baz2

如果不是,为什么?对我来说,这看起来是一个很好且安全的优化。我可以向正确的方向“提示”或“强制”编译器吗?有哪些更快的替代方案?

我想将该模式用于我的迭代器/可迭代算法集合,因此我可以将它们写为过滤器/映射/等collection.baz(lambda).bar(lambda2),但我担心它会被证明太“重”。(与更高效/直接但丑陋的相比bar(lambda2, baz(lambda, collection)

4

1 回答 1

3

正如@om-nom-nom 评论,这里的解决方案(在 2.10 中)是使用隐式值类。

implicit class RichFoo(val f : Foo) extends AnyVal {
  def baz = f.bar()
  def bax = f.bar()
}

RichFoo现在在编译时存在,但在运行时它被优化为静态方法调用,因此不会造成性能损失。

请参阅值类 (SIP)

另请参阅 Mark Harrah 的Value Classes 简介,它从使用的角度给出了很好的概述。

于 2013-03-07T14:01:59.740 回答