scala是否有可能专注于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 :(得分:48)
所以,我认为您在询问for-comprehension中的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不会更改集合的类型。但是,您可以编写自己的类来执行此操作。
答案 1 :(得分:5)
是的,你可以 - 请参考this tutorial以获得一个简单的例子。您引用的scala查询示例也在对集合进行迭代,然后使用该数据构建查询。