gpt4 book ai didi

java - Scala:特征扩展了 java.nio.file.FileVisitor

转载 作者:行者123 更新时间:2023-11-30 08:18:18 25 4
gpt4 key购买 nike

我每天都在 Scala 中学习新东西。我当前采取的路线是从 java nio 中提取功能并从中实现 Scala 实现。我观察到其他 Scala 专家如何使用 java.nio.files 包和 FileVisitor 接口(interface)递归地遍历包含子目录和文件的嵌套目录结构。

但是,我遇到了一个小问题。我不太明白

我注意到 github 上有一个由 paulp 维护的实现,我无法理解。我将在这里展示他的代码,以及我的问题和疑虑:

import java.nio.file.{ FileVisitResult, SimpleFileVisitor }

trait PathVisitor extends FileVisitor[Path] {
def preVisitDirectory(dir: Path, attrs: BasicFileAttributes): FileVisitResult
def postVisitDirectory(dir: Path, exc: IOException): FileVisitResult
def visitFile(file: Path, attrs: BasicFileAttributes): FileVisitResult
def visitFileFailed(file: Path, exc: IOException): FileVisitResult
}

好吧,他继承自 FileVisitor,这是一个 Java 接口(interface):起初,我不确定 Scala 特征是否可以从 java 接口(interface)扩展。我在 REPL 中对此进行了测试。显然这没问题。 REPL 输出如下:

C:\Users\lulu\Documents\GitHub\akkaexperiments>scala欢迎使用 Scala 版本 2.10.2(Java HotSpot(TM) 64 位服务器 VM、Java 1.7.0_71)。输入表达式以对其进行求值。输入 :help 以获取更多信息。

scala> 导入 java.nio.file.{ FileVisitor };导入java.nio.file.FileVisitor

scala> 导入 java.nio.file.Path导入java.nio.file.Path

scala> 特征 PathVisitor 扩展了 FileVisitor[Path]定义特征 PathVisitor

scala>

<小时/>

解决了这个问题,我现在查看 FileVisitor.java 的源代码。如下: 这就是保罗有趣的地方。下面的代码后面有解释。

  public interface FileVisitor<T> {
FileVisitResult preVisitDirectory(T dir);

FileVisitResult preVisitDirectoryFailed(T dir, IOException exc);

FileVisitResult visitFile(T file, BasicFileAttributes attrs);

FileVisitResult visitFileFailed(T file, IOException exc);

FileVisitResult postVisitDirectory(T dir, IOException exc);

}

---------------------

paulp's code continues below:

object PathVisitor {
class Simple extends SimpleFileVisitor[Path] with PathVisitor { }

val Continue = FileVisitResult.CONTINUE
val SkipSiblings = FileVisitResult.SKIP_SIBLINGS
val SkipSubtree = FileVisitResult.SKIP_SUBTREE
val Terminate = FileVisitResult.TERMINATE

def apply(f: (Path, BasicFileAttributes) => FileVisitResult): PathVisitor = new Simple {
override def visitFile(file: Path, attrs: BasicFileAttributes): FileVisitResult = f(file, attrs)
}

}

------

For context and comparison purposes here is the code for SimpleFileVisitor:

public class SimpleFileVisitor<T> implements FileVisitor<T> {

protected SimpleFileVisitor() {
}

@Override
public FileVisitResult preVisitDirectory(T dir, BasicFileAttributes attrs)
throws IOException
{
Objects.requireNonNull(dir);
Objects.requireNonNull(attrs);
return FileVisitResult.CONTINUE;
}

@Override
public FileVisitResult visitFile(T file, BasicFileAttributes attrs)
throws IOException
{
Objects.requireNonNull(file);
Objects.requireNonNull(attrs);
return FileVisitResult.CONTINUE;
}

@Override
public FileVisitResult visitFileFailed(T file, IOException exc)
throws IOException
{
Objects.requireNonNull(file);
throw exc;
}

@Override
public FileVisitResult postVisitDirectory(T dir, IOException exc)
throws IOException
{
Objects.requireNonNull(dir);
if (exc != null)
throw exc;
return FileVisitResult.CONTINUE;
}

}
<小时/>

经过这一切,我得出以下结论:class Simple 扩展了 SimpleFileVisitor,它是 Java FileVisitor 接口(interface)的实现

paulp还混合了PathVisitor特征,其方法定义与Java FileVisitor接口(interface)中的方法定义完全相同。

这里令我困惑的是:1)为什么他在扩展 SimpleFileVisitor 的同时还混合了 PathVisitor 特征?2)当Simple类是相同的方法时,我们是否不想要求Simple类同时遵守SimpleVisitor契约和FileVisitor特征未实现的方法?3) 他包装了 Simple Class、一堆代表 SimpleFileVisitor 方法的返回类型的 val 和一个 apply 方法。好的,那么您认为这种结构背后的想法是什么?

我真的很想使用 PaulP 提出的结构,但这令人困惑。也许它需要一些清理。请指教。

最佳答案

这样做的原因是为了提供无缝的 Scala 体验。首先,第一个特征不是抽象您可能有访问者的任何 T,而是指定路径。如果您确实只对路径感兴趣,那么不必担心泛型就好了。

然后他以 Scala 风格为您提供常量,这样您就不必从 Java 中获取它们。

他为您提供了一个特定于路径的 SimpleFileVisitor,无需任何额外的工作,只需混合 PathVisitor 特征即可。

现在,问题仍然是:为什么要这样做而不是仅仅说

type PathVisitor = java.nio.file.FileVisitor

有两个原因。首先,类型别名并不是真正一流的语言构造,因此您会倾向于看到 Java 类型而不是 Scala 类型(稍微不太好)。此外,如果您以这种方式进行设置,您以后可以更轻松地将功能添加到框架中。如果您确定不想添加任何内容,那么这样做就没有什么争议。

现在,对于具体问题:

  1. 我们混合在 PathVisitor 中,这样我们就有了一个可以移动和操作的 Scala 特定类型;我们从 Java SimpleFileVisitor 获取实现,但使其具有 Scala 特征。

  2. 要求遵守多个匹配的方法不是问题;相同的方法可以是多个特征的 API 的一部分。关键是你是否可以使用你想要的特征(即 PathVisitor;答案是"is")。

  3. 本地提供的 Scala 样式常量有助于清理导入并提供更无缝的体验,就像 apply 样式构建器而不是 new 一样。

关于java - Scala:特征扩展了 java.nio.file.FileVisitor,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29354517/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com