Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

null as instance of a type parameter

Ok, I know better than to use nulls as a design choice, but in this case I have to. Why the following does not compile?

def test[T<:AnyRef](o :Option[T]) :T = o getOrElse null

Error:(19, 53) type mismatch;
               found   : Null(null)
               required: T
               Note: implicit method foreignKeyType is not applicable here because it comes  after the application point and it lacks an explicit result type
def test[T<:AnyRef](o :Option[T]) :T = o getOrElse null
                                                   ^
like image 661
Turin Avatar asked Dec 04 '22 04:12

Turin


2 Answers

Null is a subtype of all reference types, but the fact that T is a subtype of AnyRef doesn't guarantee that T is a reference type -- in particular, Nothing is a subtype of AnyRef which does not contain null.

Your code Works if you add a lower bound:

def test[T >:Null <:AnyRef](o :Option[T]) :T = o getOrElse null;

It works:

scala> def test[T >:Null <:AnyRef](o :Option[T]) :T = o getOrElse null;
test: [T >: Null <: AnyRef](o: Option[T])T

scala> 

scala> 

scala> test(None)
res0: Null = null

scala> test(Some(Some))
res1: Some.type = Some
like image 185
jsalvata Avatar answered Dec 15 '22 19:12

jsalvata


I don't know why this does not work - Null is a subtype of all reference types in Scala, so you would expect that this would work with any T <: AnyRef. You can make it work with asInstanceOf:

def test[T <: AnyRef](o: Option[T]): T = o getOrElse null.asInstanceOf[T]

(Try to avoid using null whenever possible in Scala - I can imagine you'd have a legitimate use case, for example when you need to pass data to Java code).

By the way, Option has a method orNull which will return the value of an option if it is a Some and null if it is None.

like image 28
Jesper Avatar answered Dec 15 '22 19:12

Jesper