我理解Ruby和Python的优点。Scala的yield是做什么的?


当前回答

val aList = List( 1,2,3,4,5 )

val res3 = for ( al <- aList if al > 3 ) yield al + 1
val res4 = aList.filter(_ > 3).map(_ + 1)

println( res3 )
println( res4 )

这两段代码是等价的。

val res3 = for (al <- aList) yield al + 1 > 3
val res4 = aList.map( _+ 1 > 3 )

println( res3 ) 
println( res4 )

这两段代码也是等价的。

Map和yield一样灵活,反之亦然。

其他回答

val aList = List( 1,2,3,4,5 )

val res3 = for ( al <- aList if al > 3 ) yield al + 1
val res4 = aList.filter(_ > 3).map(_ + 1)

println( res3 )
println( res4 )

这两段代码是等价的。

val res3 = for (al <- aList) yield al + 1 > 3
val res4 = aList.map( _+ 1 > 3 )

println( res3 ) 
println( res4 )

这两段代码也是等价的。

Map和yield一样灵活,反之亦然。

除非你能从Scala用户那里得到更好的答案(我不是),以下是我的理解。

它仅作为以for开头的表达式的一部分出现,该表达式说明如何从现有列表生成新列表。

喜欢的东西:

var doubled = for (n <- original) yield n * 2

因此,每个输入都有一个输出项(尽管我相信有一种方法可以删除重复项)。

这与yield在其他语言中所支持的“命令式延续”有很大不同,在其他语言中,它提供了一种方法,可以从一些具有几乎任何结构的命令式代码生成任意长度的列表。

(如果你熟悉c#,它更接近LINQ的选择操作符,而不是yield return)。

是的,正如Earwicker所说,它几乎等同于LINQ的select,与Ruby和Python的yield关系不大。基本上,在c#中你会写

from ... select ??? 

而在Scala中则相反

for ... yield ???

同样重要的是要理解for推导式不仅适用于序列,还适用于任何定义了特定方法的类型,就像LINQ:

如果你的类型只定义map,它允许由 单独的发电机。 如果它定义了flatMap和map,则允许for-expression组成 几个发电机。 如果定义了foreach,则允许for循环而不产生yield(单个和多个生成器都可以)。 如果它定义了filter,则允许以If开头的for-filter表达式 在for表达式中。

根据Scala文档,它清楚地说“从现有的集合中生成一个新的集合”。

另一个Scala文档说,“Scala提供了一种轻量级符号来表示序列推导。推导式的形式为(enums) yield e,其中enums指以分号分隔的枚举数列表。枚举器可以是引入新变量的生成器,也可以是过滤器。”

Yield比map()更灵活,参见下面的示例

val aList = List( 1,2,3,4,5 )

val res3 = for ( al <- aList if al > 3 ) yield al + 1 
val res4 = aList.map( _+ 1 > 3 ) 

println( res3 )
println( res4 )

yield将像这样输出结果:List(5,6),这很好

而map()将返回如下结果:List(false, false, true, true, true),这可能不是你想要的。