scala - 到处使用 Option 感觉有点尴尬。难道我做错了什么?

标签 scala scala-option

由于我阅读了有关 Option 的文章帮助您避免 NullPointerException 的类,我开始到处使用它。想象一下这样的事情:

var file:Option[File] = None

后来当我使用它时:
val actualFile = file.getOrElse(new File("nonexisting"))
if(actualFile.getName.equals("nonexisting")) { // instead of null checking

}
else { // value of file was good

}

做这样的事情对我来说并不那么“正确”。我也注意到 .get已被弃用。 .你们也在用Option做这种事情,还是我走错了路?

最佳答案

返回 Option 通常不是一个好主意然后使用 getOrElse产生一些表示“未找到”的哨兵值。就是这样Option用于:表示未找到值!
Option当与函数式编程结构(如 map)结合使用时,真正显示出它的威力。和 foreach .这在处理多个选项时最为有效。例如,假设我编写了一个方法,它接受一个字符串并返回一个文件,但前提是该文件存在并且是一个文件而不是目录:

import java.io._;
def niceFile1(s: String): File = {
  val f = new File(s);
  if (f.exists && !f.isDirectory) f else null
}
def niceFile2(s: String): Option[File] = {
  val f = new File(s);
  if (f.exists && !f.isDirectory) Some(f) else None
}

到目前为止,使用 null更容易——至少直到你忘记这可能会给你带来 null你会得到一个 NPE。无论如何,让我们现在尝试使用它。
def niceFopen1(s: String) = {
  val f = niceFile1(s);
  if (f!=null) new FileInputStream(f) else null;
}
def niceFopen2(s: String) = niceFile2(s).map(f => new FileInputStream(f))

看看发生了什么!在前一种情况下,我们必须手动进行逻辑测试并创建临时变量。啊!在第二种情况下,map为我们做了所有肮脏的工作: None 被映射到 None,和 Some(file)被映射到 Some(fileinputstream) .简单!

但它变得更好了。也许我们想找到一大堆文件的大小:
def totalSize2(ss: Seq[String]) = {
  (0L /: ss.flatMap(niceFile2)){(sum,f) => sum+f.length}
}

等等,这里发生了什么事——所有的None呢? ?难道我们不需要注意并以某种方式处理它们吗?嗯,这就是flatMap进来:它将所有答案连接到一个列表中。 None是长度为零的答案,因此它忽略它。 Some(f)有一个答案-- f - 所以它把它放在列表中。然后我们使用折叠将所有长度相加——现在列表中的所有元素都是有效的。很不错!

关于scala - 到处使用 Option 感觉有点尴尬。难道我做错了什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2476835/

相关文章:

javascript - Play Framework : javascripts in scala code?

scala - 从包装在 Option[] 中的对象读取多个变量

scala - 如何产生多个值?

scala - 将 AnyRef 装箱到选项中的方法在哪里?

scala - scala 有恒等函数吗?

scala - 找不到参数 marshaller : spray. httpx.marshalling.ToResponseMarshaller 的隐式值

scala - 带有来自 shell 的 CLI 参数的“sbt run”

scala - 解释 - 不涉及反射

generics - scala:如何创建一个通用类型,该通用类型是scala中所有数字类的子类型,以便它可以包含compare方法

Scala 选项 - 摆脱 if (opt.isDefined) {}