一个访客真的是一个没有功能的好处,所以让我们做一个foreach.该方法是静态的,但它将Path作为第一个参数,因此我们将使用foreach方法丰富Path,这可以通过以下方式完成:
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.可能存在一些错误.