加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

Scala:过滤强制评估整个Stream

发布时间:2020-12-16 08:48:19 所属栏目:安全 来源:网络整理
导读:以下代码从类的构造函数中调用一次的方法本身调用一次.当它作为规范UnitTest的一部分执行时,测试卡住了,并且生成了一个快速消耗更多内存的 javaw进程. private def placeMines( excludes: List[( Int,Int )] ) { def rndstream: Stream[( Int,Int )] = { def
以下代码从类的构造函数中调用一次的方法本身调用一次.当它作为规范UnitTest的一部分执行时,测试卡住了,并且生成了一个快速消耗更多内存的 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 =>真正.有趣的是,它终结于真实的情况下,但始终以虚假的方式运行.插入一些printlns表明,在终止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流过滤器强制评估”和“scala流过滤器不终止”只提出了一些教程,展示了原则上与我的代码相同的流的用法.

解决方法

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

拿你的示例流并调用

s.filter(_ => false)

这不会返回,所以它必须是你的过滤功能.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读