6

我在某处找到了 C# 空合并运算符'??'的实现:

implicit def coalescingOperator[T](pred: T) = new {
  def ??[A >: T](alt: =>A) = if (pred == null) alt else pred
}

然后可以像a ?? bwhich mean一样使用它if (a == null) b else a

在反编译类文件后,我看到它生成了带有反射的代码(在 Scala 2.8.1 中)。

为什么它会产生反射,是否可以修改该代码使其不会产生反射?

4

1 回答 1

12

Scala 没有与 Java 相同的匿名类概念。如果你说类似

new {
  def fish = "Tuna"
}

然后它将把新方法的所有使用解释为需要结构类型,即与

def[T <: {def fish: String}](t: T) = t.fish

由于没有通用的超类,因此需要使用反射。我不知道为什么会这样;对于性能而言,这完全是错误的做法,而且通常不是您所需要的。

无论如何,修复很简单:创建一个实际的类,而不是匿名类。

class NullCoalescer[T](pred: T) {
  def ??[A >: T](alt: => A) = if (pred == null) alt else pred
}
implicit def anyoneCanCoalesce[T](pred: T) = new NullCoalescer(pred)

在 2.10 中,它仍然会做可以说是错误的事情,但是(1)它会向您发出警告,因为您以这种方式使用反射(因此至少您会知道它何时发生),除非您将其关闭,并且(2)您可以使用较短的版本implicit class /* blah blah */并跳过implicit def仅添加样板的版本。

于 2012-05-28T16:33:04.097 回答