首页 文章

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

提问于
浏览
3

在我的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 回答

  • 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]Int 之间的最佳常见类型),因此您的匹配必须假设该项目的类型为 Any ,这实际上消除了有用性这里的类型检查器 .

    您应该调整 Seq ,使其具有更好的通用类型 . 如果您使用 Option[Student] 作为超时未来的返回类型,则它可能返回 NoneSeq 将是 Seq[Future[Option[Student]]] . 然后 map 可以假设您在 Option[Student] 上匹配 .

相关问题