在父特征

时间:2017-09-16 23:17:07

标签: scala types type-mismatch

我对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)

也尝试使用自我类型,它给了我同样的错误。

1 个答案:

答案 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

您不能为方法toTableNothing <: TableQuery[Table[_]]提供实施。