我在某处找到了C#空合并运算符'??'的实现:
implicit def coalescingOperator[T](pred: T) = new {
def ??[A >: T](alt: =>A) = if (pred == null) alt else pred
}
然后可以像
a ?? b
一样使用它,意味着if (a == null) b else a
。在对类文件进行反编译之后,我看到它会生成带有反射的代码(在Scala 2.8.1中)。
为什么它会产生反射,并且有可能修改该代码,使其不会产生反射?
最佳答案
Scala与Java没有相同的匿名类概念。如果你说类似
new {
def fish = "Tuna"
}
然后它将新方法的所有用法解释为需要结构类型,即与
def[T <: {def fish: String}](t: T) = t.fish
由于没有通用的父类(super class),因此需要使用反射。我不知道为什么会这样。对于性能而言,这完全是错误的事情,通常也不是您所需要的。
无论如何,解决方法很容易:创建一个实际的类,而不是一个匿名类。
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
。
关于scala - 是否可以在不使用反射的Scala中实现 `??`(C#中的空合并运算符)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10787480/