jwi*_*ndy 6 scala manifest scala-2.9
在Scala 2.9.1中
同
def collectFirstOfT[T](la: List[_])(implicit m:Manifest[T]) : Option[T] = {
la.collect{case x if m.erasure.isAssignableFrom(x.getClass) => x}.
headOption.asInstanceOf[Option[T]]}
class A
class B
Run Code Online (Sandbox Code Playgroud)
为什么这个表达:
val oB:Option[B] = collectFirstOf(List(new A,new B))
Run Code Online (Sandbox Code Playgroud)
编译,但收集一些(A),但
val oB =collectFirstOf[B](List(new A,new B))
Run Code Online (Sandbox Code Playgroud)
工作良好.
如何从Option [T]中推断T?
您必须将以下行视为两个独立的部分,= 的左侧和右侧:
val oB: Option[B] = collectFirstOf(List(new A,new B))
Run Code Online (Sandbox Code Playgroud)
您在这里期望的是,collectFirstOf 表达式(右值)的类型应该从值 oB 的类型推断出来。编译器无法做到这一点。您必须具体说明您期望的类型。举个例子:
val v: Long = 1 + 4
Run Code Online (Sandbox Code Playgroud)
表达式 1 + 4 的类型是 Int。然后将此 int 转换为 Long。编译器不会,也无法推断出您希望 1 或 4 为 Long:
因此,要解决您的问题,您需要告诉编译器您期望什么类型,否则它会假定 java.lang.Object:
val oB = collectFirstOf[B](List(new A,new B))
Run Code Online (Sandbox Code Playgroud)
因此清单被正确分配,一切都很好。那么为什么下面的代码甚至可以编译:
val oB:Option[B] = collectFirstOfT(List(new A,new B))
oB: Option[B] = Some(A@10f3a9c)
Run Code Online (Sandbox Code Playgroud)
乍一看,这似乎不起作用,但确实如此。这是因为collectFirstOfT实际上返回一个Option[Nothing],它可以安全地转换为Option[B]:
scala> val f = collectFirstOfT(List(new A,new B))
f: Option[Nothing] = Some(A@baecb8)
scala> f.asInstanceOf[Option[B]]
res4: Option[B] = Some(A@baecb8)
Run Code Online (Sandbox Code Playgroud)