更多Scala输入问题

问题描述

| 现在,Kim Stebel帮助我理解了如何使用存在性类型键入变量,我需要知道如何在继承中使用它们: 以下代码无法编译:
class PagingListModel(startPageNumber: Int,pageSize: Int,query: Query[Projection[_ <: Product]]) extends AbstractListModel {
    val itemStartNumber: Int = startPageNumber * pageSize
    val items: List[Product] = getPageData()

    override def getPageData(): List[Product] = {
        db withSession {
            return queryToQueryInvoker(query.drop(itemStartNumber).take(pageSize)).list
        }
    }
}
…出现错误
no type parameters for method queryToQueryInvoker:
(q: org.scalaquery.ql.Query[org.scalaquery.ql.ColumnBase[T]])
org.scalaquery.ql.basic.BasicQueryInvoker[T]
exist so that it can be applied to arguments
(org.scalaquery.ql.Query[org.scalaquery.ql.Projection[_ <: Product]])
--- because ---
argument expression\'s type is not compatible with formal parameter type;
found :   org.scalaquery.ql.Query[org.scalaquery.ql.Projection[_ <: Product]]
required: org.scalaquery.ql.Query[org.scalaquery.ql.ColumnBase[?T]]
…这很奇怪,因为所需的类型实际上在找到的类型的范围之内… PS:我真的只希望能够在
getPageData()
返回的列表中的每个元组调用
foreach
...     

解决方法

我不认为存在类型可以做到这一点。它与类型参数一起使用:
class PagingListModel[T <: Product](... query: Query[Projection[T]]) {
  ...
  def getPageData(): List[_ <: Product] = ...
    queryToQueryInvoker(query.drop(itemStartNumber).take(pageSize)).list
}
原始版本是正确的,但是由于类似于Haskell的单态性限制,Scala无法对其进行类型检查。 queryToQueryInvoker的类型参数必须是Scala不支持的通用类型ѭ5supported。 通过使用显式类型参数,可以使用该特定类型实例化queryToQueryInvoker。该方法仍然可以返回“ 6”,因为List的元素类型是协变的。 编辑:毕竟是可能的。您必须将存在对象移到正确的位置:
class PagingListModel(... query: Query[Projection[T]] forSome { type T <: Product })  {
  def getPageData(): List[_ <: Product] = ... {
    val i = queryToQueryInvoker(query.drop(itemStartNumber).take(pageSize))
    i.list
  }
}
如果没有额外的变量“ 8”,编译器将推断错误的类型,然后对其进行抱怨。对我来说似乎是个虫子。     ,我对ScalaQuery的了解是有限的,但似乎您应该对类进行参数化。
class PagingListModel[T <: Product] (
  startPageNumber: Int,pageSize: Int,query: Query[Projection[T]]
) extends AbstractListModel {
  ...
}
存在可能很棘手,最好尽可能避免。