在我的Play + Reactive Mongo应用程序中,我收到了Future [Option [Student]]结果,我想要匹配结果:
def getStudent(id: String)=Action {
val futureOfStudent:Future[Option[Student]] = StudentRepository.getStudentById(id)
val timeoutFuture = play.api.libs.concurrent.Promise.timeout(0, Duration(3000, MILLISECONDS))
Async {
Future.firstCompletedOf(Seq(futureOfStudent, timeoutFuture)).map {
case s: Option[Student] => {s match {case Some(s)=>Ok(Json.toJson(s))
case None => NoContent}}
case i: Int => InternalServerError("Oooppppps!!!")
}
}
}
一切都像魅力一样,但我在case s: Option[Student] =>
- non-variable type argument model.Student in type pattern
Option[modelStudent] is unchecked since it is eliminated by erasure
如何解决此警告?
我用Google搜索并发现了一些文章:
How do I get around type erasure on Scala? Or, why can't I get the type parameter of my collections?
Why does Scala warn about type erasure in the first case but not the second?
但是,它没有给我一些线索如何解决作为Play控制器的一部分。
请帮忙。
答案 0 :(得分:3)
类型擦除的问题是您不能再使用类型参数:Option[Student]
在运行时看起来像Option[_]
。这导致了以下问题:
val opt: Option[Student] = Some(myStudent)
opt match {
case s: Option[String] => println('problem') // this would happen
case s: Option[Student] => // this wouldn't get called
}
解决问题的最简单方法可能就是......
case s: Option[_] => s match {
case Some(student: Student) => Ok(Json.toJson(student))
case _ => NoContent
}
但这并没有真正解决问题的根源。您创建的Seq
包含Future[Option[Student]]
和Future[Int]
,因此它可能会解析为Seq[Future[Any]]
(Option[Student]
和{{1}之间的最佳常见类型}),所以你的匹配必须假设该项是Int
类型,这实际上删除了类型检查器的有用性。
您应调整Any
以使其具有更好的通用类型。如果您使用Seq
作为超时未来的返回类型,则可能会返回Option[Student]
,而None
将是Seq
。然后,Seq[Future[Option[Student]]]
可以假设您在map
上匹配。