2011-10-31 99 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查询例子也在迭代集合,然后使用这些数据来构建查询。