【问题标题】:null as instance of a type parameternull 作为类型参数的实例
【发布时间】:2015-02-08 12:59:13
【问题描述】:

好吧,我知道最好不要使用空值作为设计选择,但在这种情况下我必须这样做。为什么以下不编译?

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
                                                   ^

【问题讨论】:

  • 你为什么不用Option.orNull
  • 这是我的第一选择,但是当它不起作用时(原因在下面的答案中给出),我试图使示例更简单。

标签: scala generics null type-parameter


【解决方案1】:

我不知道为什么这不起作用 - Null 是 Scala 中所有引用类型的子类型,所以您希望这适用于任何 T &lt;: AnyRef。您可以使用asInstanceOf

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

(尽量避免在 Scala 中使用 null - 我可以想象你会有一个合法的用例,例如当你需要将数据传递给 Java 代码时)。

顺便说一句,Option 有一个方法 orNull,如果它是 Somenull 如果它是 None,它将返回一个选项的值。

【讨论】:

  • 如果使用参数 None 调用,这将是 NPE。
  • 在 REPL 中,但这可能是 REPL 的副作用。在 REPL 中试试这个:test(None: Option[String])
  • 你是对的。尽管如此,使用 >:Null 而不是 <:anyref .asinstanceof>
【解决方案2】:

Null 是所有引用类型的子类型,但 T 是 AnyRef 的子类型这一事实并不能保证 T 是引用类型——特别是,Nothing 是 AnyRef 的子类型,它不包含 null。

如果您添加下限,您的代码将有效:

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

有效:

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

【讨论】:

  • 需要下限因为Nothing &lt;: Null。否则,您可以使用test[Nothing](None) 创建Nothing 的实例。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-07-12
  • 1970-01-01
  • 1970-01-01
  • 2010-09-20
  • 1970-01-01
相关资源
最近更新 更多