在我的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
将是什么)。看一下实现,我应该提供隐含的证据,证明null
是T
的有效值:
@inline final def orNull[A1 >: A](implicit ev: Null <:< A1): A1 = this getOrElse ev(null)
现在,我的问题是:我怎样才能提供这样的证据? ev
应该是什么类型,我该如何为它创建一个值?
答案 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
时,您可以在方法中添加相同的隐式参数(或者,对于<:<
,特别是类型绑定),以及调用它的方法等,直到您来到特定类型。