5

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 ^ 
2
  • why don't you use Option.orNull? Commented Dec 10, 2014 at 11:13
  • 1
    It was my first choice, but when it didn't work (for reason given in the answer below) I tried to make the the example simpler. Commented Dec 10, 2014 at 19:06

2 Answers 2

12

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 
Sign up to request clarification or add additional context in comments.

1 Comment

The lower bound is needed because Nothing <: Null. Otherwise, you could create an instance of Nothing using test[Nothing](None).
5

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.

3 Comments

This will NPE if called with parameter None.
In the REPL, but that might be a side-effect of the REPL. Try this in the REPL: test(None: Option[String])
You're right. Still, the solution of using >:Null instead of <:AnyRef (which is equivalent, because all reference types fall in between these two) is cleaner than using .asInstanceOf.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.