1

有人可以解释一下 REPL 的以下输出吗?

我正在定义 2 个(无限)流,它们在其他方面的定义相同,除了map前面是. (句点)在一个定义中,而 _ _(空格)在另一个定义中。

我可以看到这会导致map以不同的方式绑定,但是第二个定义的输出中的1会发生什么?

谢谢。

scala> lazy val infinite: Stream[Int] = 1 #:: infinite.map(_+1)
infinite: Stream[Int] = <lazy>

scala> val l = infinite.take(10).toList.mkString(",")
l: String = 1,2,3,4,5,6,7,8,9,10

scala> lazy val infinite2: Stream[Int] = 1 #:: infinite2 map(_+1)
infinite2: Stream[Int] = <lazy>

scala> val l2 = infinite2.take(10).toList.mkString(",")
l2: String = 2,3,4,5,6,7,8,9,10,11
4

2 回答 2

11

这是关于方法关联性的。这:

1 #:: infinite.map(_+1)

很简单,而这:

1 #:: infinite2 map(_+1)

编译器将其解释为:

(1 #:: infinite2) map(_+1)

1 #:: infinite2是您想要的流,但在您返回它之前,您应用惰性转换为每个项目添加一个。这就解释了为什么1从来没有作为结果出现——在转换之后它变成了2

有关更多详细信息,请参阅:Scala 中的运算符优先级。由于#不是特殊字符,因此与 同等对待map,因此方法从左到右进行评估。

于 2012-12-05T18:31:34.720 回答
1

在infinite2 的情况下,您所表达的内容等同于以下内容:

lazy val infinite2: Stream[Int] = (1 #:: infinite2) map(_ + 1)

由于流以 1 开头,因此 map 会将 1 添加到第一个元素。

于 2012-12-05T18:39:17.880 回答