2011-05-26 60 views
2

现在,金Stebel helped me understanding如何与存在的类型类型变量,我需要知道如何在继承使用它们:更多斯卡拉打字问题

下面的代码无法编译:

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:我真的只是想能够调用foreach在由getPageData()返回列表中的每个元组...

回答

2

我不认为这可以用存在型进行。它的工作原理与一类参数:

class PagingListModel[T <: Product](... query: Query[Projection[T]]) { 
    ... 
    def getPageData(): List[_ <: Product] = ... 
    queryToQueryInvoker(query.drop(itemStartNumber).take(pageSize)).list 
} 

原始版本是正确的,但斯卡拉不能将其类型检查,由于类似Haskell的单态限制的限制。 queryToQueryInvoker的类型参数必须是通用类型[T <: Product] forAll { type T },Scala不支持该参数。

通过使用显式类型参数,可以使用该特定类型实例化queryToQueryInvoker。该方法仍然可以返回List[_ <: Product],因为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 
    } 
} 

如果没有额外的变量i编译器会推断错误的类型,然后抱怨。对我来说看起来像一个bug。

+0

我会考虑 – 2011-05-29 12:10:23

+0

看起来不错!这绝对是我从未想过整个该死的时间,我试图找到我的错误的一件事... – 2011-05-29 12:20:18

1

我ScalaQuery的知识是有限的,但它看起来好像你应该参数化的类。

class PagingListModel[T <: Product] (
    startPageNumber: Int, 
    pageSize: Int, 
    query: Query[Projection[T]] 
) extends AbstractListModel { 
    ... 
} 

存在可能会很棘手,如果可能的话最好避免。

+0

我想到了这一点,但是当构建查询时,如何使用它的类型作为类型参数呢? – 2011-05-29 12:09:22

+0

你不需要明确类型参数。编译器将根据您提供的“Projection”类型作为参数为您确定它。 – 2011-05-29 21:08:10

+0

听起来很有用... – 2011-05-29 21:28:46