我对Scala编程很新。除了Scala之外,我还没有学过函数式编程。话虽如此,我现在正试图找出一个使用光滑的项目定义特征,类等的好方法。
我的想法是让一个特性具有在子类上实现的方法,一些特性将在父类本身上实现。我发现了一种有效的方法,但我不知道为什么。不确定此问题是否与Slick或Scala如何工作有关。
我使用的结构如下:
trait CompanyDAO extends BaseDao[Company]{
self: DBProfile =>
但这会导致以下类型不匹配错误:
[错误]发现: slick.lifted.TableQuery [CompanyDAO.this.CompanyTable] [错误] 需要: slick.lifted.TableQuery [CompanyDAO.this.profile.api.Table [公司]] [错误](扩展为) slick.lifted.TableQuery [CompanyDAO.this.profile.Table [公司]] [错误]注:CompanyDAO.this.CompanyTable<: CompanyDAO.this.profile.api.Table [Company],但类TableQuery是 类型E中的不变量。[错误]您可能希望将E定义为+ E。 (SLS 4.5)[错误]覆盖def toTable = TableQuery [CompanyTable]
但是,如果我使用
self: DBProfile with BaseDao[Company] =>
然后编译工作(BTW,从another post获得解决方案)
所以,我的问题:
1)为什么在扩展特性时使用自我类型toTable赋值不起作用? scala如何在两种场景中解释toTable的类型?
2)有没有办法适应"特性CompanyDAO扩展BaseDao"解决错误?
提前谢谢。
import scala.concurrent.Future
import slick.basic.DatabaseConfig
import slick.jdbc.JdbcProfile
trait DBConfiguration {
lazy val config = DatabaseConfig.forConfig[JdbcProfile]("mytrade")
}
trait DBProfile {
val config: DatabaseConfig[JdbcProfile]
val db: JdbcProfile#Backend#Database = config.db
val profile : JdbcProfile = config.profile
}
trait BaseDao[T <: Any] {
self: DBProfile =>
import profile.api._
import slick.lifted.TableQuery
def toTable():TableQuery[Table[T]]
def findAll():Future[Seq[T]] = db.run(toTable.result)
}
case class Company(name: String, code: Int)
// If I use the construction like the comment below, it will fail
//trait CompanyDAO extends BaseDao[Company]{
//self: DBProfile =>
trait CompanyDAO {
self: DBProfile with BaseDao[Company] =>
//import from DBProfile trait
import profile.api._
class CompanyTable(tag: Tag) extends Table[Company](tag, "COMPANY") {
import slick.ast.BaseTypedType
import slick.jdbc.JdbcType
def name = column[String]("name")
def code = column[Int]("code")
def * = (name, code) <> (Company.tupled, Company.unapply)
}
override def toTable = TableQuery[CompanyTable]
}
编辑:我一直在尝试的其他一些事情
扩展BaseDao,如果我将toTable的声明更改为:
def toTable[S <: TableQuery[Table[_]]]():S
类型不匹配消失但我现在收到:
test.scala:27:此构造后的死代码[error] def findAll():Future [Seq [T]] = db.run(toTable.result)
也尝试使用自我类型,它给了我同样的错误。
答案 0 :(得分:0)
如果我将toTable的声明更改为:
def toTable[S <: TableQuery[Table[_]]]():S
类型不匹配消失但我现在收到:
test.scala:27: dead code following this construct [error] def findAll():Future[Seq[T]] = db.run(toTable.result)
任何想法为什么会发生这种情况?
我无法重现您的特定编译错误。
但是当我改变这条线时
def toTable():TableQuery[Table[T]]
到
def toTable[S <: TableQuery[Table[_]]]():S
我有编译错误
Error:(24, 51) value result is not a member of Nothing
def findAll():Future[Seq[T]] = db.run(toTable.result)
这是因为类型参数S
被推断为Nothing
。
您不能为方法toTable
和Nothing <: TableQuery[Table[_]]
提供实施。