斯卡拉:流动不懒惰?
我知道溪流应该是
Scala中的懒惰评估序列,但是我认为我正在遭受某种根本的误解,因为它们似乎比我预料的更加渴望.
在这个例子中: val initial = Stream(1) lazy val bad = Stream(1/0) println((initial ++ bad) take 1) 我得到一个java.lang.ArithmeticException,这似乎是由零除法引起的.我会期望不会得到评估,因为我只是从流中要一个元素.怎么了? 解决方法
好的,所以在评论其他答案后,我想我可以把我的意见变成一个正确的答案.
流确实是懒惰的,只会根据需要计算其元素(您可以使用#::按元素构造流元素,很像:: for List).例如,以下不会抛出任何异常: (1/2) #:: (1/0) #:: Stream.empty 这是因为当应用#::时,尾部按名称传递,以便不要热切地评估它,但只有在需要时(请参阅Cons.Wrapper.#:: const.apply和Stream.scala中的类缺点以获取更多详细信息). (1/0) #:: Stream.empty 这是一个值得了解流的东西.但是,这不是您面临的问题. 在你的情况下,算术异常发生在甚至实例化单个流之前.当在lazy val bad = Stream(1/0)中调用Stream.apply时,该参数被强制执行,因为它不被声明为by name参数. Stream.apply实际上需要一个vararg参数,而这些参数必须通过值传递.即使它被名字传递,ArithmeticException将不久之后被触发,因为如前所述,Stream的头部总是被早期评估. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |