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


当前回答

它用于序列推导式(就像Python的列表推导式和生成器一样,在这里你也可以使用yield)。

它与for结合应用,并将一个新元素写入结果序列。

简单示例(来自scala-lang)

/** Turn command line arguments to uppercase */
object Main {
  def main(args: Array[String]) {
    val res = for (a <- args) yield a.toUpperCase
    println("Arguments: " + res.toString)
  }
}

f#中对应的表达式为

[ for a in args -> a.toUpperCase ]

or

from a in args select a.toUpperCase 

在Linq中。

Ruby的产量有不同的影响。

其他回答

为了理解,考虑以下内容

val A = for (i <- Int.MinValue to Int.MaxValue; if i > 3) yield i

大声读出来可能会有帮助

对于每一个整数i,如果它大于3,那么yield (produce) i并将其添加到列表a中。

在数学集合构建符号方面,上面的for-comprehension类似于

这可以理解为

"对于每一个整数,如果它大于,那么它就是集合中的成员"

或者作为替代

"是所有整数的集合,每个都大于"

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一样灵活,反之亦然。

Yield类似于for循环,它有一个我们看不到的缓冲区,对于每一个增量,它都会不断向缓冲区中添加下一项。当for循环结束运行时,它将返回所有产生值的集合。Yield可以用作简单的算术运算符,甚至可以与数组结合使用。 为了更好地理解,这里有两个简单的例子

scala>for (i <- 1 to 5) yield i * 3

res: scala.collection.immutable。IndexedSeq[Int] = Vector(3,6,9,12,15)

scala> val nums = Seq(1,2,3)
nums: Seq[Int] = List(1, 2, 3)

scala> val letters = Seq('a', 'b', 'c')
letters: Seq[Char] = List(a, b, c)

scala> val res = for {
     |     n <- nums
     |     c <- letters
     | } yield (n, c)

res: Seq [(Int、Char)] =列表((1),(b)、(1 c), (2), (2 b), (2 c), (3), (b)、(3 c))

希望这能有所帮助!!

关键字yield在Scala中只是简单的语法糖,可以很容易地用映射替换,Daniel Sobral已经详细解释过了。

另一方面,如果你在寻找类似于Python中的生成器(或延续),yield绝对会误导你。查看这个SO线程以获得更多信息:在Scala中实现“yield”的首选方式是什么?

val doubledNums = for (n <- nums) yield n * 2
val ucNames = for (name <- names) yield name.capitalize

注意,这两个for表达式都使用了yield关键字:

在for之后使用yield是“秘密武器”,它表示“我想从我在for表达式中迭代的现有集合中生成一个新的集合,使用所示的算法。”

从这里开始