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

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

本文介绍了使用从不同范围导入时的Scala类型不匹配问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

In my project(play 2.4 with slick 3.0), I have a setup: using MySQL for production and H2 for unit testing(start to feel that it is a horrible idea). To do that, I have to import slick.driver.JdbcProfile instead of any specific driver (e.g. slick.driver.MySQLDriver) and import its api._ in my DAO class, like this:

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

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

  // other DBIO...

}

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

Everything is OK so far, however, I have a service class that requires this DAO, and a type in context as a parameter:

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

}

当我尝试从完全相同的context实例导入类型时出现问题,从直觉上讲,我在这里使用的是"相同"类型,对吗?

Problem heppens when I try to import a type from exact the same context instance, intuitively speaking, I'm using the "Same" type here, right?

有人可以解释这种行为,并给我一些模式提示,以减少我写的这种废话"吗?

Can someone explain this kind of behaviour and give hint about patterns to cut this kind of 'non-sense' I wrote?

推荐答案

您正在使用依赖于路径的类型.它们实际上是依赖于路径,而不是路径的内容.

You are using path-dependent types. They are literally dependent on paths, not on its content.

考虑该示例:

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实际上是相同的,它们共享相同的内容和相同的类型.内容正确.类型错误.编译器很好地为您提供了类型错误:

You may assume naively that x and y are practically identical, they share the same content and the same type. True for the content. Wrong for types. And compiler nicely provide you with a type error:

找到的:dependent.Assign.x.Box [Int]

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

必填:dependent.Assign.y.Box [Int]

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

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

But you could tell the compiler that x and y should share the same path-dependent types despite being different literal paths

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定义以接受类型参数

Your issue has the similar nature, and the solution is similar too: you should specify type equivalence explicitly. Change the SameDAO definition to accept type parameter

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

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

and pass appropriate type upon creation:

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

这篇关于使用从不同范围导入时的Scala类型不匹配问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-05 11:10