Scala如何不执行此功能?

时间:2013-12-26 12:06:57

标签: scala

为了练习一点Scala,我决定为我的iTunes库实现一个清洁工。任务是删除链接断开的库条目。

这是主要部分:

def findExistingSongs(lib:Seq[Node]) = {
  val songs = lib \ "dict" \ "dict" \\ "dict" //main->tracks
  songs.filter(song => (song \ "dict" \ "string").exists(value => value.text.startsWith("file://localhost/") && fileExists(value.text)))
}

def fileExists(url:String) = {
  val path = url.replaceAll("file://localhost","").replaceAll("%20"," ")
  println(path)
  val file = new File(path)
  file.exists
}

使用玩具库测试时,我可以清楚地看到println(path)语句只执行一次。如果我只是将&& fileExists部分更改为&& !fileExists,则会对库中的每个条目执行print语句。

我读到了Scala memoization,但fileExists函数与文件系统接口,所以不应该优化它。从逻辑POV开始,您也无法决定不需要再次调用它,因为每个调用的参数值都会更改,结果取决于它。 最后,如果Scala只执行一次但是当它被否定时,它怎么才有意义呢?

1 个答案:

答案 0 :(得分:3)

方法collection.exists{predicate}遍历集合,直到找到第一个元素epredicate(e) == true。当它获得这样的元素时,它已经知道集合中的这个元素存在,所以不需要搜索第二个这样的元素。

val predicate = { i: Int => println(s"$i > 0 == ${i > 0}"); i > 0 }

(-1 to 3) exists predicate 
// -1 > 0 == false
// 0 > 0 == false
// 1 > 0 == true
// res0: Boolean = true

(1 to 3) exists predicate
// 1 > 0 == true
// res1: Boolean = true

正如您可以看到existstrue首先predicate之后停止。{/ p>

exists就像find一样:您将使用collection.find(predicate).nonEmpty获得相同的结果。