使用从不同范围导入时的 Scala 类型不匹配问题

标签 scala playframework-2.0 slick type-mismatch

在我的项目(玩 2.4 和 slick 3.0)中,我有一个设置:使用 MySQL 进行生产,使用 H2 进行单元测试(开始觉得这是一个可怕的想法)。为此,我必须导入 slick.driver.JdbcProfile 而不是任何特定的驱动程序(例如 slick.driver.MySQLDriver)并导入其 api._ 在我的 DAO 类中,如下所示:

class SomeDAO(val context: MyContext){
  import context.profile.api._
  import context.SOME_TYPE

  def invoke(para: SOME_TYPE) = { ... }

  // other DBIO...

}

到目前为止,一切都很好,但是,我有一个需要此 DAO 的服务类,以及上下文中的类型作为参数:

class MyService(val context: MyContext){

   val someDAO = new SomeDAO(context)
   import someDAO.context.SOME_TYPE  // it works
   // import context.SOME_TYPE   // Type mismatch! But how to avoid it???

   def invokeDAOMethod(para: SOME_TYPE) = someDAO.invoke(para) // where mismatch occurred
   // expect: MyService.this.someDao.context.SOME_TYPE
   // actual: MyService.this.context.SOME_TYPE

}

当我尝试从完全相同的上下文实例导入类型时,就会出现问题,直观地说,我在这里使用“相同”类型,对吗?

有人可以解释这种行为并给出一些模式提示来减少我写的这种“无意义”吗?

最佳答案

您正在使用路径相关类型。它们实际上依赖于路径,而不是其内容。

考虑这个例子:

class Store {
  case class Box[T](box : T)
  def box[T](b : T) = Box[T](b)
  def unbox[T](b : Box[T]) : T = b.box
}

object Assign {
  val x = new Store()
  val y = x
  val box = x.box[Int](2)
  val ub = y.unbox[Int](box)
}

您可能天真地认为xy实际上是相同的,它们共享相同的内容和相同的类型。内容真实。类型错误。编译器很好地为您提供了类型错误:

error: type mismatch;

found : dependent.Assign.x.Box[Int]

required: dependent.Assign.y.Box[Int]

但是您可以告诉编译器,xy 应该共享相同的路径相关类型,尽管文字路径不同

object Assign {
  val x = new Store()
  val y : x.type = x
  val box = x.box[Int](2)
  val ub = y.unbox[Int](box)
}

使用 val y : x.type = x 编译器将会成功。

您的问题具有相似的性质,解决方案也相似:您应该明确指定类型等效性。更改 SameDAO 定义以接受类型参数

class SomeDAO[MC <: MyContext](val context: MC){
  ...
}

并在创建时传递适当的类型:

class MyService(val context: MyContext){
  val someDAO = new SomeDAO[context.type](context)
  ...
}

关于使用从不同范围导入时的 Scala 类型不匹配问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32692936/

相关文章:

scala - 关闭 Slick 注销

windows - 为什么 Play 在 Windows 上为类报告 java.lang.NoClassDefFoundError(而在 Linux 上运行良好)?

scala - 在 Scala 中的 Free Monad 中堆叠 Monadic 效果

scala - 如何在Scala中产生格式正确的XML?

scala - 使用 SBT : Invalid or corrupt jarfile 构建 Apache Spark

java - 我如何检索通过java play中的post传递的数据

javascript - 玩 scala 浏览图像然后裁剪并提交到表单中

java - 如何在 Play 中切换生产和开发数据库配置?

scala - 防火墙后面的 Akka 对等点

slick - 我如何将 scalaz-streams 连接到 react 性流(如reactive-streams.org)