乔什·苏雷什 (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 中所做的那样在每一步检查空值。如您所见,这里没有发生很多类型推断。
我认为您困惑的根源可能是
map
和 filter
(除其他外)通常与某种类型的集合相关联,因此可能很难理解它们在 Option 上所做的事情,而 Option 仅与集合非常相似。为此,我向您推荐经典 scala.Option cheat sheet
关于java - 被 "Scala in Depth"选项示例混淆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9777217/