2011-05-26 69 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