使用来自不同范围的导入时的 Scala 类型不匹配问题
Scala Type Mismatch issue when using import from different scope
在我的项目中(用 slick 3.0 玩 2.4),我有一个设置:使用 MySQL 进行生产,使用 H2 进行单元测试(开始觉得这是一个可怕的想法)。为此,我必须导入 slick.driver.JdbcProfile
而不是任何特定的驱动程序(例如 slick.driver.MySQLDriver
)并将其 api._
导入我的 DAO class,如下所示:
class SomeDAO(val context: MyContext){
import context.profile.api._
import context.SOME_TYPE
def invoke(para: SOME_TYPE) = { ... }
// other DBIO...
}
到目前为止一切正常,但是,我有一个服务 class 需要这个 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
}
当我尝试从完全相同的 context
实例中导入一个类型时出现问题,直观地说,我在这里使用的是“Same”类型,对吧?
有人可以解释这种行为并给出有关模式的提示以削减我写的这种 'non-sense' 吗?
通过将类型定义移动到 object
来减少痛苦,因此类型是静态导入的。
仍然不确定如何继承类型以及如何在其中引入一些动态组件object
更新: 它实际上在 Scala 中被称为 "Path Dependent Types"。
您正在使用依赖于路径的类型。它们实际上取决于路径,而不是其内容。
考虑这个例子:
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)
}
您可能会天真地认为 x
和 y
实际上是相同的,它们共享相同的内容和相同的类型。真实的内容。错误的类型。编译器很好地为您提供了类型错误:
error: type mismatch;
found : dependent.Assign.x.Box[Int]
required: dependent.Assign.y.Box[Int]
但是你可以告诉编译器 x
和 y
应该共享相同的路径相关类型,尽管它们是不同的文字路径
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)
...
}
在我的项目中(用 slick 3.0 玩 2.4),我有一个设置:使用 MySQL 进行生产,使用 H2 进行单元测试(开始觉得这是一个可怕的想法)。为此,我必须导入 slick.driver.JdbcProfile
而不是任何特定的驱动程序(例如 slick.driver.MySQLDriver
)并将其 api._
导入我的 DAO class,如下所示:
class SomeDAO(val context: MyContext){
import context.profile.api._
import context.SOME_TYPE
def invoke(para: SOME_TYPE) = { ... }
// other DBIO...
}
到目前为止一切正常,但是,我有一个服务 class 需要这个 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
}
当我尝试从完全相同的 context
实例中导入一个类型时出现问题,直观地说,我在这里使用的是“Same”类型,对吧?
有人可以解释这种行为并给出有关模式的提示以削减我写的这种 'non-sense' 吗?
通过将类型定义移动到 object
来减少痛苦,因此类型是静态导入的。
仍然不确定如何继承类型以及如何在其中引入一些动态组件object
更新: 它实际上在 Scala 中被称为 "Path Dependent Types"。
您正在使用依赖于路径的类型。它们实际上取决于路径,而不是其内容。
考虑这个例子:
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)
}
您可能会天真地认为 x
和 y
实际上是相同的,它们共享相同的内容和相同的类型。真实的内容。错误的类型。编译器很好地为您提供了类型错误:
error: type mismatch;
found : dependent.Assign.x.Box[Int]
required: dependent.Assign.y.Box[Int]
但是你可以告诉编译器 x
和 y
应该共享相同的路径相关类型,尽管它们是不同的文字路径
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)
...
}