返回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
————所以它把它放在列表中。然后我们使用折叠将所有长度相加——现在列表中的所有元素都是有效的。挺好的!