首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Scala:特性扩展了java.nio.file.FileVisitor

Scala:特性扩展了java.nio.file.FileVisitor
EN

Stack Overflow用户
提问于 2015-03-30 19:23:58
回答 1查看 375关注 0票数 1

我每天都在Scala学习新东西。我目前采用的方法是从java中提取功能,并将Scala实现从它们中提取出来。我已经观察到其他Scala专家如何使用java.nio.files包,以及FileVisitor接口递归地遍历带有子目录和文件的嵌套目录结构。

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

我注意到由paulp维护的github上的一个实现,我不能使用understand.It作为他的代码,我将在这里展示我的问题和关注:

代码语言:javascript
复制
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接口:首先,我不确定Scala特性是否可以从java接口扩展。我在REPL中测试了这个。很明显这没问题。REPL的产出如下:

C:\Users\lulu\Documents\GitHub\akkaexperiments>scala欢迎使用ScalaVersion2.10.2 (Java (TM)64位服务器VM,Java1.7.0_71).键入要对它们进行计算的表达式。类型:帮助获取更多信息。

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

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

scala>属性PathVisitor扩展了FileVisitorPath定义的特征PathVisitor

scala>

在此之后,我看了一下FileVisitor.java的源代码。下面是:这是paulp引人入胜的地方。下面是下面的代码之后的解释。

代码语言:javascript
复制
  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;
    }  

}

在此之后,我做了以下观察:类Simple扩展了SimpleFileVisitor,它是FileVisitor接口的实现

另外,特征PathVisitor中的paulp混合,其方法定义与接口中的方法定义完全相同。

让我感到困惑的是: 1)为什么他同时扩展了SimpleFileVisitor,同时也混合了PathVisitor特性? 2)我们是不是想让类简单地遵守SimpleVisitor契约和FileVisitor特性未实现的方法,当它们是相同的方法时? 3)他封装了简单类、一堆表示SimpleFileVisitor方法的返回类型的值和一个应用方法。好吧,你认为这种结构背后的想法是什么?

我真的很想使用PaulP布局的结构,但这是令人费解的。可能需要清理一下。请给我建议。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-04-02 02:17:54

这样做的原因是为了提供无缝的Scala体验。首先,第一个特征是指定路径,而不是抽象出您可能需要访问的任何T。如果你真的只对路径感兴趣,不用担心泛型是件好事。

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

他给出了一个路径特定的SimpleFileVisitor,而不需要额外的工作,只需混合PathVisitor特性即可。

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

代码语言:javascript
复制
type PathVisitor = java.nio.file.FileVisitor

有两个原因。首先,类型别名并不是真正的一流语言结构,所以您将倾向于看到Java类型而不是Scala类型(稍微不太好)。另外,如果您以这种方式设置它,那么以后可以更容易地将功能添加到框架中。如果您确信您不想添加任何内容,那么这样做的理由就更少了。

现在,关于具体问题:

  1. 我们混合了PathVisitor,所以我们有一个特定于Scala的类型,我们可以移动和操作;我们从SimpleFileVisitor获得实现,但是让它获得Scala的特性。
  2. 请求尊重多个匹配的方法并不是问题;相同的方法可以是多个特征API的一部分。关键是你是否可以使用你想要的特质(即PathVisitor;答案是“是”)。
  3. Scala风格的常量在本地提供有助于清理您的导入并提供更无缝的体验,apply-style构建器而不是new也是如此。
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29354517

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档