Is it possible to implement `??` (the zero coalescing operator from C #) in Scala that does not use reflection?

I found somewhere the implementation of the C # null coalescing '??' operator:

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

Then it can be used as a ?? b a ?? b , which means if (a == null) b else a .

And after decompiling the class files, I saw that it was creating code with reflection (in Scala 2.8.1).

Why does it generate reflection and is it possible to change this code so that it does not generate reflection?

+6
source share
1 answer

Scala does not have the same idea of ​​anonymous classes as Java. If you say something like

 new { def fish = "Tuna" } 

then he will interpret all applications of the new method as requiring a structural type, i.e. same as

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

which should use reflection as there is no common superclass. I do not know why this is so; this is not what you need to do for performance, and usually it is not what you need.

Regardless, fixing it is easy: create an actual class, not anonymous.

 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) 

In 2.10, it still does the wrong thing, but (1) it will give you warnings to use reflection in this way (so at least you will know when it will happen) if you don't turn them off, and (2) you you can use a shorter version of the implicit class /* blah blah */ and skip the implicit def , which just adds the pattern.

+12
source

Source: https://habr.com/ru/post/916856/


All Articles