Scala:过滤器强制整个流的求值



从在类的构造函数中调用一次的方法本身调用一次以下代码。当它作为spec单元测试的一部分被执行时,测试会卡住,并且会产生一个javaw进程,它会快速消耗更多的内存。

private def placeMines( excludes: List[( Int, Int )] ) {
    def rndstream: Stream[( Int, Int )] = {
        def s: Stream[( Int, Int )] =
            ( Random.nextInt( ysize ), Random.nextInt(  xsize ) ) #:: s
        s
    }
    def posPermitted( pos: ( Int, Int ) ): Boolean = {
        !excludes.contains( pos ) &&
            fieldEmpty( pos._1, pos._2 )
    }
    val positions = rndstream.filter( posPermitted )
    positions.take( minecount ).foreach( x => grid( x._1 )( x._2 ) = MineField() )
}

为了找出发生了什么,我已经用副作用(网格是一个二维数组)注释掉了最后一行,并用不同的过滤器谓词替换了过滤器谓词,包括x => false和x => true。有趣的是,它在真情况下终止,但在假情况下永远运行。插入一些println显示谓词在终止java进程之前被调用了数十万次。

我试着用下面的代码重现这种情况:

import scala.util.Random
import org.specs.SpecificationWithJUnit
class foobar extends SpecificationWithJUnit {
    val x = 0xDead
    val y = 0xBeef
    bar(x, y)
    private def bar(x: Int, y: Int) = foo(x)
    private def foo(x: Int) = {
        def s: Stream[( Int, Int )] = {
            def p: Stream[( Int, Int )] =
                ( Random.nextInt( x ), Random.nextInt( y ) ) #:: p
            p
        }
        val fiveodd = s.filter( x => x._1 % 2 == 1 )
        println( fiveodd.take( 5 ).toList )
    }
}

但是代码运行得很好。

搜索"scala流过滤器无穷无尽"scala流过滤器强制求值"one_answers"scala流过滤器不会终止",只会出现一些教程,展示了流的用法,这些教程似乎与我的代码在原则上是相同的。

我猜你的过滤器功能有问题。Stream.filter尝试找到第一个匹配的值,如果没有,它将永远搜索。

取您的示例流并调用

s.filter(_ => false)

这个将不会返回,所以它必须是你的过滤器函数

相关内容

  • 没有找到相关文章

最新更新