有人可以解释一下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
答案 0 :(得分:11)
关于method associativity。这样:
1 #:: infinite.map(_+1)
非常简单:
1 #:: infinite2 map(_+1)
由编译器解释为:
(1 #:: infinite2) map(_+1)
1 #:: infinite2
是您想要的流,但在您返回之前,您应用延迟转换,为每个项添加一个。这解释了为什么1
永远不会出现的结果 - 转换后它变为2
。
有关详细信息,请参阅:Operator precedence in Scala。由于#
不是特殊字符,因此它与map
同等对待,因此方法从左到右进行评估。
答案 1 :(得分:1)
在无限的情况下,你所表达的内容相当于以下内容:
lazy val infinite2: Stream[Int] = (1 #:: infinite2) map(_ + 1)
由于流以1开头,因此地图将向第一个元素添加1。