Scala 的 for-comprehension `if` 语句 [英] Scala's for-comprehension `if` statements

查看:28
本文介绍了Scala 的 for-comprehension `if` 语句的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

scala 是否有可能在 for comprehension 中专门处理 if 中的条件?我在思考:

Is it possible in scala to specialize on the conditions inside an if within a for comprehension? I'm thinking along the lines of:

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 类型.

The gist is that by yielding i, I get a new collection of a potentially different type (hence me referring to it as "specialization")- as opposed to just a filtered-down version of the same GenericCollection type.

我问的原因是我看到了一些我无法弄清楚的东西(可以找到一个例子在这个 ScalaQuery 示例的第 33 行.它所做的是为数据库创建一个查询(即 SELECT ... FROM ... WHERE ...),我原以为它会遍历上述查询的结果.

The reason I ask is that I saw something that I couldn't figure out (an example can be found on line 33 of this ScalaQuery example. What it does is create a query for a database (i.e. SELECT ... FROM ... WHERE ...), where I would have expected it to iterate over the results of said query.

推荐答案

所以,我想您是在问是否可以在 for-comprehension 中使用 if 语句来更改结果类型.答案是是的,但是……".

So, I think you are asking if it is possible for the if statement in a for-comprehension to change the result type. The answer is "yes, but...".

首先,了解 for-comprehensions 是如何扩展的.Stack Overflow 上有一些问题在讨论它,您可以将参数传递给编译器,以便它向您展示发生了什么.

First, understand how for-comprehensions are expanded. There are questions here on Stack Overflow discussing it, and there are parameters you can pass to the compiler so it will show you what's going on.

无论如何,这段代码:

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

翻译为:

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

所以,如果 withFilter 方法改变了集合类型,它会做你想做的——在这个简单的例子中.在更复杂的情况下,单独这样做是行不通的:

So, if the withFilter method changes the collection type, it will do what you want -- in this simple case. On more complex cases, that alone won't work:

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

翻译为

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

在这种情况下,flatMap 决定返回什么类型.如果它从返回的结果中得到提示,那么它就可以工作.

In which case flatMap is deciding what type will be returned. If it takes the cue from what result was returned, then it can work.

现在,在 Scala 集合上,withFilter 不会改变集合的类型.不过,您可以编写自己的类来实现这一点.

Now, on Scala Collections, withFilter doesn't change the type of the collection. You could write your own classes that would do that, however.

这篇关于Scala 的 for-comprehension `if` 语句的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆