Question

I wonder what is the reason for the (implicit ev: Null <:< A1) here:

sealed abstract class Option[+A] extends Product with Serializable { 
  def orNull[A1 >: A](implicit ev: Null <:< A1): A1 = this getOrElse null
  ...
}

Wouldn't

def orNull[A]: A = this getOrElse null

be enough considering that it doesn't even seem to work with value types like

Option(1).orNull

but

Option(1).getOrElse(null)

does?

Option's source code

Was it helpful?

Solution

Not all scala types can be null. In particular, Any has two children, AnyRef and AnyVal. AnyRef can handle null types. AnyVal types could be primitives on the JVM and therefore cannot be null. The implicit is a delayed type-check that allows Option[String] to use orNull but not Option[Int].

Note: This dichotomy of Int being boxed/unboxed object/primitive has very strange manifestations in Scala, such as null.asInstanceOf[Int] == 0 // true.

OTHER TIPS

scala> abstract class Op[A] {
     |   def getOrElse(b: A): A
     |   def orNull[A]: A = this getOrElse null
     | }
<console>:14: error: type mismatch;
 found   : Null(null)
 required: A
         def orNull[A]: A = this getOrElse null
                                           ^

So, null is not an acceptable type for all A, only for the nullable ones. The subclasses of AnyVal are typical examples of non-nullable types. In the absence of that parameter, it is not possible to write this method.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top