无法证明Null<:< Ť

时间:2016-07-06 20:18:17

标签: scala optional

在我的Scala代码中,我有一个Option[T]数组,如下所示:

val items = Array.fill[Option[T]](10)(None)

现在,我想从该数组中读取特定项目;如果尚未设置,我想拥有null。但当我做items(desiredIndex).orNull时,Scala编译器对我大喊:

Error:(32, 34) Cannot prove that Null <:< T.
      (items(desiredIndex).orNull).asInstanceOf[T]

我不完全理解这个错误。我所理解的是,编译器无法推断null确实是T的有效值(因为不知道T将是什么)。看一下实现,我应该提供隐含的证据,证明nullT的有效值:

@inline final def orNull[A1 >: A](implicit ev: Null <:< A1): A1 = this getOrElse ev(null)

现在,我的问题是:我怎样才能提供这样的证据? ev应该是什么类型,我该如何为它创建一个值?

2 个答案:

答案 0 :(得分:6)

按类型绑定:

scala> def f[T >: Null : ClassTag]: T = {
     | val items = Array.fill[Option[T]](10)(None)
     | items(0).orNull }
f: [T >: Null](implicit evidence$1: scala.reflect.ClassTag[T])T

scala> f[String]
res3: String = null

Per Pedro:

scala> def f[T >: Null]: T = Array.fill[Option[T]](10)(None).apply(0).orNull
f: [T >: Null]=> T

答案 1 :(得分:2)

虽然som-snytt给出的解决方案对于这个特定情况更简单,更好,但直接回答问题:

  

应该是什么类型

Null <:< A1(这只是写<:<[Null, A1])的另一种方式。

  

如何为其创建值

对于您不需要的特定类型,编译器将自己提供此证据(使用scala.Predef.$conforms)。但是在使用泛型T时,您可以在方法中添加相同的隐式参数(或者,对于<:<,特别是类型绑定),以及调用它的方法等,直到您来到特定类型。