scala - 为什么我需要一个额外的 asInstanceOf
问题描述
我写了这段代码
listOfClassNames.map{ className =>
Try {
GuiceInjector.getInstance(Class.forName(className)).asInstanceOf[BaseClass]
} recover {
case _ => Option.empty[(String, BaseClass)]
} match {
case Success(bc) => Some((className, bc))
case _ => Option.empty[(String, BaseClass)]
}
}
上面的代码抛出错误
type mismatch;
[error] found : List[Option[(String, Object)]]
[error] required: List[Option[(String, BaseClass)]]
现在,如果我将代码更改为
listOfClassNames.map{ className =>
Try {
GuiceInjector.getInstance(Class.forName(className)).asInstanceOf[BaseClass]
} recover {
case _ => Option.empty[(String, BaseClass)]
} match {
case Success(bc) => Some((className, bc.asInstanceOf[BaseClass]))
case _ => Option.empty[(String, BaseClass)]
}
}
现在它起作用了。但根据我的说法,第二个 asInstanceOf 是不必要的,因为第一个对象本身是类型转换的。不?
解决方案
您必须删除对 的调用recover
。无论如何都不需要它,因为您在内部处理错误案例match
,但它会弄乱代码的类型和正确性。
考虑类型:Try { /* ... */.asInstanceOf[BaseClass] }
有类型Try[BaseClass]
。
然后Try { /* ... */ } recover { case _ => Option.empty[(String, BaseClass)] }
是andTry
的常见超类型,所以它是。BaseClass
Option[(String, BaseClass)]
Try[AnyRef]
因此,在case Success(bc) =>
this中的 match 内部bc
有 type AnyRef
,并且在运行时它可以是BaseClass
or的一个实例None
。BaseClass
如果从 Guice的原始获取失败,这bc
是None
,你会得到一个ClassCastException
带有附加的isInstanceOf
.