如何使用yield for multistatement for?

问题描述:

该代码仅用于说明目的,即它是一个示例不是一个真实的代码。如何使用yield for multistatement for?

我尝试这样做:

val results = for(i <- 1 to 20) 
{ 
    val x = i+1 
    println(x) 
    yield x 
} 

val results = for {i <- 1 to 20; 
    val x = i+1; 
    println(x) 
} 
    yield x 

但这一切工作 - 我需要一台发电机,定义和声明 - 这是可能的用收益率做?如果是,那么正确的语法是什么?

希望这将让你开始:

val result = for (i <- 1 to 10 if i%2==0) yield { 
    println(i); 
    i 
    } 

这相当于

(1 to 10).filter(_%2==0).map(x => { println(x); x }) 
+0

太棒了,我不知道产量可能是一个结果表达块。 – greenoldman 2011-12-15 12:42:04

你似乎认为for在Scala是在命令式语言类似for。不是!在幕后,它使用了flatMapfor/yield语法的第一部分中的每个表达式都必须具有某种形式。如果我没有弄错,它必须是一个任务(限制为val,也许)或<-表达式。你可以破解它得到你想要的:

for { 
    i <- 1 to 20 
    val x = i + 1 
    _ <- {println(x); List(1)} 
} yield x 

但这是非常可怕的。正如Jamil所示,黑客yield也是一种可能性,虽然也非常可怕。

问题是,你到底想要完成什么? foreach最适用于副作用的循环代码:

(1 to 10) foreach { i => 
    val x = i+1 
    println(x) 
} 

map最适用于生产相同长度的新名单:

(1 to 10) map (i => i + 1) 

这是相当不寻常的,而且有点难看,想同时做两个。

+0

谢谢,但请注意2件事。随着foreach你没有得到任何结果,并与地图你没有得到任何声明(它是可以修复的)。我试图完成什么?它取决于任务 - 它简化为这三个:发生器+定义+语句,产生新的序列。问题是优雅 - 对我来说,更优雅的地图,这就是为什么我尝试使用+收益。 – greenoldman 2011-12-15 12:45:28