java - 被 "Scala in Depth"选项示例混淆

标签 java scala option type-inference

乔什·苏雷什 (Josh Sueresh) 所著的曼宁新书“深入 Scala”的第 2 章已发布 here .在阅读这篇文章时,我遇到了这段代码:

def getTemporaryDirectory(tmpArg : Option[String]) : java.io.File = {

   tmpArg.map(name => new java.io.File(name)).

          filter(_.isDirectory).

       getOrElse(new java.io.File(System.getProperty("java.io.tmpdir")))

}

解释上述代码的后续文本如下:

The getTemporaryDirectory method takes the command line parameter as an Option containing a String and returns a File object referencing the temporary directory we should use. The first thing we do is use the map method on Option to create a java.io.File if there was a parameter. Next, we make sure that this newly constructed file object is a directory. To do that, we use the filter method. This will check whether the value in an Option abides by some predicate and, if not, convert to a None. Finally, we check to see if we have a value in the Option; otherwise, we return the default temporary directory.



所以,对于我来自 Java 并学习 Scala 来说,代码语法让我感到困惑。我不明白 map(...) 函数调用后面是怎么有一个点的。似乎发生了太多类型推断,我在某处遗漏了一些东西并且没有看到类型。

这对我学习 Scala 非常有帮助,能够以某种方式看到所有推断的类型,取消推断(或取消应用)所有的减少,即看起来像 Java 6 之前的类型的过于冗长的版本在集合类的等号两边明确。

是否有任何工具可以使用 Scala 代码片段并明确不同的东西(可能作为标志;一个用于类型,另一个用于隐式,另一个用于大括号,另一个用于分号)。我只需要一些东西来引导我从完全简洁的代码到更接近 Java 的东西,这样我就可以自信地建立我在阅读(并最终编写)更简洁的 Scala 方面的技能。

这是我正在寻找的东西:
def getTemporaryDirectory(tmpArg : Option[String]) : java.io.File = {

   ContainerType1[Type1] t1 = tmpArg.map(name => new java.io.File(name));
   ContainerType2[Type2] t2 = t1.filter(_.isDirectory);
   return t2.getOrElse(new java.io.File(System.getProperty("java.io.tmpdir")));

}

我并没有特别坚持上面的内容。由于类型推断,我无法根据实际发生的情况了解链式函数调用的工作方式。对此的任何帮助将不胜感激。

最佳答案

好吧,你确实有 REPL 来一个一个地尝试链接命令并检查它们的结果类型,但我不确定看到签名会对你有多大帮助:

scala> Some("c:\\users\\paolo")
res0: Some[java.lang.String] = Some(c:\users\paolo)

scala> res0.map(name => new java.io.File(name))
res1: Option[java.io.File] = Some(c:\users\paolo)

scala> res1.filter(_.isDirectory)
res2: Option[java.io.File] = Some(c:\users\paolo)

scala> res2.getOrElse(new java.io.File(System.getProperty("java.io.tmpdir")))
res3: java.io.File = c:\users\paolo

现在让我们再试一次,从 None 开始。
scala> None:Option[String]
res6: Option[String] = None

scala> res6.map(name => new java.io.File(name))
res7: Option[java.io.File] = None

scala> res7.filter(_.isDirectory)
res8: Option[java.io.File] = None

scala> res8.getOrElse(new java.io.File(System.getProperty("java.io.tmpdir")))
res9: java.io.File = C:\Users\paolo\AppData\Local\Temp

所以使用 Option帮助我们“传播”了None无需像我们在 Java 中所做的那样在每一步检查空值。

如您所见,这里没有发生很多类型推断。
我认为您困惑的根源可能是 mapfilter (除其他外)通常与某种类型的集合相关联,因此可能很难理解它们在 Option 上所做的事情,而 Option 仅与集合非常相似。
为此,我向您推荐经典 scala.Option cheat sheet

关于java - 被 "Scala in Depth"选项示例混淆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9777217/

相关文章:

java - 如何在 wffweb 中正确渲染 HTML 树中的任意文本内容

java - 无法使用 zip4j 在 java 中创建 zip 文件

java - 当从 Collection 生成源时,Flink 不进行检查点,BucketingSink 会将文件置于挂起状态

scala - 对 Apache-Spark 数据帧中的距离求和

java - 从 Linux 上的 Java 获取卷标

java - 如何在 Scala 中获取 Java 的 int.class?

Scala:通过异常处理来组合 future 的结果

Scala:如何明确比较两个选项?

visual-studio - 如何告诉 Visual Studio 2010 记住“查找”对话框的位置?

scala - 使用Scalaz将选项列表转换为列表选项