訪客是真的foreach
沒有功能的好處,所以讓我們做一個foreach
。該方法是靜態的,但它需要作爲第一個參數Path
,所以我們會充實Path
與foreach
方法,它是用什麼做這樣的:
import java.nio.file._
import java.nio.file.attribute.BasicFileAttributes
implicit def fromNioPath(path: Path): TraverseFiles = new TraversePath(path)
和其他一切是TraversePath
類,在其內部看起來有點像這樣:
class TraversePath(path: Path) {
def foreach(f: (Path, BasicFileAttributes) => Unit) {
// ...
}
}
這是足以讓你寫:
ProjectHome foreach ((file, _) => if (!file.toString.contains(".svn")) println(File))
當然,實際上並不會做任何事情,讓我們把它做一些事情:
class TraversePath(path: Path) {
def foreach(f: (Path, BasicFileAttributes) => Unit) {
class Visitor extends SimpleFileVisitor[Path] {
override def visitFile(file: Path, attrs: BasicFileAttributes): FileVisitResult = try {
f(file, attrs)
FileVisitResult.CONTINUE
} catch {
case _ => FileVisitResult.TERMINATE
}
}
Files.walkFileTree(path, new Visitor)
}
}
在那裏,現在該行會做同樣的事情,你的代碼做了!但是,我們可以進一步改進它。碰巧foreach
是Traversable
所需的唯一方法,所以我們可以擴展該類,並獲得Scala集合的所有方法!
唯一的問題是Traversable.foreach
函數只有一個參數,在這裏我們取兩個參數。不過,我們可以將它改爲接收元組。下面是完整的代碼:
import java.nio.file._
import java.nio.file.attribute.BasicFileAttributes
import scala.collection.Traversable
// Make it extend Traversable
class TraversePath(path: Path) extends Traversable[(Path, BasicFileAttributes)] {
// Make foreach receive a function from Tuple2 to Unit
def foreach(f: ((Path, BasicFileAttributes)) => Unit) {
class Visitor extends SimpleFileVisitor[Path] {
override def visitFile(file: Path, attrs: BasicFileAttributes): FileVisitResult = try {
// Pass a tuple to f
f(file -> attrs)
FileVisitResult.CONTINUE
} catch {
case _ => FileVisitResult.TERMINATE
}
}
Files.walkFileTree(path, new Visitor)
}
}
ProjectHome foreach {
// use case to seamlessly deconstruct the tuple
case (file, _) => if (!file.toString.contains(".svn")) println(File)
}
免責聲明:我已經測試沒有這個代碼,因爲我安裝了Java 7沒有做。可能有一些錯誤。