Возможно ли это осуществить??` (нулевой коалесцирующий оператор из C#) в Scala, который не использует отражение?


Я где-то нашел реализацию оператора коалесцирования c# null '??':

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).

Почему он генерирует отражение и можно ли модифицировать этот код, чтобы он не генерировал отражение?

1 6

1 ответ:

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, который просто добавляет шаблонность.