scala - 是否可以在不使用反射的Scala中实现 `??`(C#中的空合并运算符)?

标签 scala reflection null-coalescing-operator structural-typing

我在某处找到了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/

相关文章:

scala - 如何在 Play Framework 中隐藏文本字段

java - 方法调用与基于反射的事件系统

javascript - 如何在添加即时特定私有(private)值时自动包装共享对象以别名现有功能

PHP null 与三元运算符合并(再次)

scala - 整数列表在scala中可以为空时的最小值

scala - 将可变对象设置为 'val' 是什么意思?

json - 使用 Scala 中的列表解析递归 JSON 结构

reflection - 为什么 == 和 equals 会产生不同的结果?

C# ??空合并运算符

c# - Null coalesce , Ternary 或 If Statement 哪个工作得更快