null as instance of a type parameter

2019-07-04 01:08发布

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条回答
Rolldiameter
2楼-- · 2019-07-04 01:28

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
查看更多
我想做一个坏孩纸
3楼-- · 2019-07-04 01:40

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.

查看更多
登录 后发表回答