gpt4 book ai didi

scala - Scala 的产量是多少?

转载 作者:行者123 更新时间:2023-12-03 04:00:34 25 4
gpt4 key购买 nike

我了解 Ruby 和 Python 的产量。 Scala的yield有什么作用?

最佳答案

我认为公认的答案很好,但似乎很多人都未能捕获一些基本点。

首先,Scala 的 for 推导式相当于 Haskell 的 do 表示法,它只不过是多个一元运算组合的语法糖。由于此声明很可能不会帮助任何需要帮助的人,让我们再试一次......:-)

Scala 的 for 推导式是用于使用 map、flatMapfilter 组合多个操作的语法糖。或者foreach。 Scala 实际上将 for 表达式转换为对这些方法的调用,因此提供它们的任何类或其子集都可以与 for 推导式一起使用。

首先,我们来谈谈翻译。有非常简单的规则:

  1. 这个

    for(x <- c1; y <- c2; z <-c3) {...}

    翻译成

    c1.foreach(x => c2.foreach(y => c3.foreach(z => {...})))
  2. 这个

    for(x <- c1; y <- c2; z <- c3) yield {...}

    翻译成

    c1.flatMap(x => c2.flatMap(y => c3.map(z => {...})))
  3. 这个

    for(x <- c; if cond) yield {...}

    在 Scala 2.7 上被翻译成

    c.filter(x => cond).map(x => {...})

    或者,在 Scala 2.8 上,进入

    c.withFilter(x => cond).map(x => {...})

    如果 withFilter 方法不可用,但 filter 可用,则回退到前者。有关详细信息,请参阅以下部分。

  4. 这个

    for(x <- c; y = ...) yield {...}

    翻译成

    c.map(x => (x, ...)).map((x,y) => {...})

当您查看非常简单的 for 推导式时,map/foreach 替代方案看起来确实更好。然而,一旦开始编写它们,您很容易迷失在括号和嵌套级别中。当这种情况发生时,for 理解通常会更加清晰。

我将展示一个简单的示例,并故意省略任何解释。您可以决定哪种语法更容易理解。

l.flatMap(sl => sl.filter(el => el > 0).map(el => el.toString.length))

for {
sl <- l
el <- sl
if el > 0
} yield el.toString.length
<小时/>

withFilter

Scala 2.8 引入了一种名为 withFilter 的方法,其主要区别在于,它不是返回新的经过过滤的集合,而是按需进行过滤。 filter 方法的行为是根据集合的严格性定义的。为了更好地理解这一点,让我们看一下带有 List (严格)和 Stream (非严格)的 Scala 2.7:

scala> var found = false
found: Boolean = false

scala> List.range(1,10).filter(_ % 2 == 1 && !found).foreach(x => if (x == 5) found = true else println(x))
1
3
7
9

scala> found = false
found: Boolean = false

scala> Stream.range(1,10).filter(_ % 2 == 1 && !found).foreach(x => if (x == 5) found = true else println(x))
1
3

之所以会出现这种差异,是因为 filter 立即与 List 一起应用,返回赔率列表 - 因为 foundfalse。只有这样 foreach 才会被执行,但是,此时,更改 found 已经没有意义了,因为 filter 已经执行了。

对于Stream,条件不会立即应用。相反,当 foreach 请求每个元素时,filter 会测试条件,这使得 foreach 能够通过 found 影响它>。为了清楚起见,下面是等效的 for 理解代码:

for (x <- List.range(1, 10); if x % 2 == 1 && !found) 
if (x == 5) found = true else println(x)

for (x <- Stream.range(1, 10); if x % 2 == 1 && !found)
if (x == 5) found = true else println(x)

这导致了许多问题,因为人们期望 if 被视为按需,而不是预先应用于整个集合。

Scala 2.8 引入了 withFilter,它始终是非严格的,无论集合的严格性如何。以下示例显示了 Scala 2.8 上使用两种方法的 List:

scala> var found = false
found: Boolean = false

scala> List.range(1,10).filter(_ % 2 == 1 && !found).foreach(x => if (x == 5) found = true else println(x))
1
3
7
9

scala> found = false
found: Boolean = false

scala> List.range(1,10).withFilter(_ % 2 == 1 && !found).foreach(x => if (x == 5) found = true else println(x))
1
3

这会产生大多数人期望的结果,而不会改变过滤器的行为方式。附带说明一下,在 Scala 2.7 和 Scala 2.8 之间,Range 从非严格更改为严格。

关于scala - Scala 的产量是多少?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1052476/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com