Khách truy cập thực sự là foreach
mà không có lợi ích của chức năng, vì vậy, hãy tạo một foreach
. Phương pháp này là tĩnh, nhưng phải mất như là đối số đầu tiên một Path
, vì vậy chúng tôi sẽ làm giàu cho Path
với một phương pháp foreach
, được thực hiện với một cái gì đó như thế này:
import java.nio.file._
import java.nio.file.attribute.BasicFileAttributes
implicit def fromNioPath(path: Path): TraverseFiles = new TraversePath(path)
Và mọi thứ khác là bên trong lớp TraversePath
, mà trông hơi như thế này:
class TraversePath(path: Path) {
def foreach(f: (Path, BasicFileAttributes) => Unit) {
// ...
}
}
này là đủ để bạn có thể viết những dòng này:
ProjectHome foreach ((file, _) => if (!file.toString.contains(".svn")) println(File))
Tất nhiên, nó sẽ không thực sự làm bất cứ điều gì, vì vậy chúng ta hãy làm cho nó làm điều gì đó:
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)
}
}
Có, bây giờ mà dòng sẽ làm điều tương tự như mã của bạn đã làm! Tuy nhiên, chúng tôi có thể cải thiện hơn nữa. Nó xảy ra rằng foreach
là phương pháp duy nhất được yêu cầu của Traversable
, vì vậy chúng tôi có thể mở rộng lớp đó và nhận tất cả các phương pháp của bộ sưu tập Scala!
Vấn đề duy nhất là hàm Traversable.foreach
chỉ nhận một đối số và ở đây chúng tôi đang lấy hai tham số. Tuy nhiên, chúng ta có thể thay đổi nó thành một tuple. Đây là mã đầy đủ:
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)
}
Tuyên bố từ chối trách nhiệm: Tôi chưa thử nghiệm mã này vì tôi chưa cài đặt Java 7. Có thể có một số lỗi.