Play框架应用程序中的Scala类型擦除警告

时间:2013-12-13 23:51:43

标签: mongodb scala playframework-2.0

在我的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控制器的一部分。

请帮忙。

1 个答案:

答案 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上匹配。