2011-10-31 98 views
18

斯卡拉可能在scala中專門研究if中的條件以便理解嗎?我沿線的思考:斯卡拉的理解`if`語句

val collection: SomeGenericCollection[Int] = ... 

trait CollectionFilter 
case object Even extends CollectionFilter 
case object Odd extends CollectionFilter 

val evenColl = for { i <- collection if(Even) } yield i 
//evenColl would be a SomeGenericEvenCollection instance 

val oddColl = for { i <- collection if(Odd) } yield i 
//oddColl would be a SomeGenericOddCollection instance 

要點是,通過產生i,我得到一個潛在的不同類型的(因此我將其稱爲「專業化」)的一個新的集合 - 而不是隻相同GenericCollection類型的過濾版本。

我問的原因是我看到了一些我找不到的東西(可以找到一個例子on line 33 of this ScalaQuery example。它的作用是創建一個數據庫查詢(即SELECT ... FROM ... WHERE ...),在那裏我會預期它迭代所述查詢的結果

+0

這個問題沒有多大意義。我要回答我認爲正在被問到的問題,但是嘗試改進它。 –

+0

['For expressions'](http://www.artima.com/pins1ed/for-expressions-revisited.html#23.1)應該有所幫助。 – 4e6

+0

我加了一點點來試圖澄清這個問題,儘管你在思考我所問的問題時似乎是正確的。 – Dylan

回答

40

所以,我想你在問是否有可能使if語句在理解中改變結果類型。答案是「是的,但是。 ..「。

首先,瞭解如何擴展理解。 Stack Overflow在討論它時存在一些問題,並且有些參數可以傳遞給編譯器,因此它會告訴你發生了什麼。

反正這個代碼:

val evenColl = for { i <- collection if(Even) } yield i 

被翻譯爲:

val evenColl = collection.withFilter(i => Even).map(i => i) 

所以,如果withFilter方法更改集合類型,它會做你想要的 - 在這個簡單的例子。在更復雜的情況下,這不會單獨工作:

for { 
    x <- xs 
    y <- ys 
    if cond 
} yield (x, y) 

被翻譯爲

xs.flatMap(ys.withFilter(y => cond).map(y => (x, y))) 

在這種情況下,flatMap是決定將返回什麼類型。如果它從返回的結果中得到提示,那麼它可以工作。

現在,在Scala Collections中,withFilter不會更改集合的類型。不過,你可以編寫你自己的類。

+0

謝謝,我認爲'withFilter'是我失蹤的關鍵信息。 – Dylan

4

是的,你可以 - 請參考this tutorial一個簡單的例子。你引用的scala查詢例子也在迭代集合,然後使用這些數據來構建查詢。