2013-07-09 69 views
1

我已经在一个宠物项目最近尝试Scala和注意到下面的代码片段是吃内存(我称这种方法很多):斯卡拉内存使用

private[this] def isConsistent(startLang2: Int, lengthLang2: Int, 
    startLang1: Int, lengthLang1: Int, 
    lang2FinalAlignments: ArrayBuffer[ArrayBuffer[Int]]): Boolean = { 

    (startLang2 to (startLang2 + lengthLang2)) foreach { 
     i => 
     val valueSeq = lang2FinalAlignments(i) 
     if (valueSeq.size == 0 || valueSeq.exists { value => value < startLang1 || value > (startLang1 + lengthLang1) }) 
      false 
    } 
    true 
} 

当我改变了“假”到‘返回false’的情况似乎已经解决了自身:

private[this] def isConsistent(startLang2: Int, lengthLang2: Int, 
    startLang1: Int, lengthLang1: Int, 
    lang2FinalAlignments: ArrayBuffer[ArrayBuffer[Int]]): Boolean = { 

    (startLang2 to (startLang2 + lengthLang2)) foreach { 
     i => 
     val valueSeq = lang2FinalAlignments(i) 
     if (valueSeq.size == 0 || valueSeq.exists { value => value < startLang1 || value > (startLang1 + lengthLang1) }) 
      return false 
    } 
    true 
} 

当我想想片断#2有道理至于我如何期望/希望的方式工作。有人可以向我解释第一个片段正在做什么?

+0

第一个片段做了一些不同的事情。这是一个不变的“真实”。 – ziggystar

+0

也许有用:http://stackoverflow.com/questions/2742719/how-do-i-break-out-of-a-loop-in-scala但是你已经知道如何使用'exists'。 –

回答

2

让我们来看看foreach做:

def foreach[U](f: Elem => U): Unit 

所以集合的每一个元素上运行f并放弃它的结果 - 它并不关心f返回类型。

在你的情况,当你调用

... foreach { 
    i => { 
    ... 
    if (...) 
     false 
    } 
true 

函数返回false的身体,如果满足条件,且Unit否则。它们的共同超类型是Any,所以传递给foreach的函数的类型为Int => Any。它的结果被丢弃并且你遍历整个集合。 (先给作为foreach[Any]foreach[Boolean]一个明确的类型等。)

在第二片段中的情况有很大的不同:

... foreach { 
    i => { 
    ... 
    if (...) 
     return false 
    } 
true 

这里foreach横穿范围仅直到满足条件然后return逃脱foreach执行并使主函数退出。