为什么foreach比获得Scala选项更好?

为什么使用foreachmapflatMap等被认为比使用scala选项更好? 如果我使用isEmpty我可以安全地调用get

那么,这回到“告诉,不要问”。 考虑这两行:

 if (opt.isDefined) println(opt.get) // versus opt foreach println 

在第一种情况下,你正在看内部opt ,然后根据你所看到的作出反应。 在第二种情况下,你只是告诉opt你想做什么,并让它处理它。

第一个案例太了解Option ,复制内部逻辑,脆弱并容易出错(如果写入不正确,可能会导致运行时错误,而不是编译时错误)。

除此之外,它不是可组合的。 如果你有三个select,一个单一的理解照顾他们:

 for { op1 <- opt1 op2 <- opt2 op3 <- opt3 } println(op1+op2+op3) 

if ,事情开始变得凌乱。

使用foreach一个很好的理由是使用嵌套选项parsing某些东西。 如果你有类似的东西

 val nestedOption = Some(Some(Some(1))) for(opt1 <- nestedOption; opt2 <- opt1; opt3 <- opt2) println(opt3) 

控制台打印1 。 如果你把这个延伸到一个你可以select存储某个引用的类的例子,这个引用又会存储另一个引用,为了理解,你可以避免一个巨大的“金字塔”无/有些检查。

对于实际问题已经有了很好的答案,但是对于更多的Option -foo,你绝对应该看看Tony Morris的选项备忘单 。

mapforeachflatMap等东西直接应用到Option而不是使用get和执行函数更有用的原因是它可以在Some None ,您不必进行特殊的检查来确保价值在那里。

 val x: Option[Int] = foo() val y = x.map(_+1) // works fine for None val z = x.get + 1 // doesn't work if x is None 

这里y结果是一个Option[Int] ,这是可取的,因为如果x是可选的,那么y也可能是不确定的。 由于getNone不起作用,所以你必须做一些额外的工作来确保你没有得到任何的错误。 额外的工作是由你完成的map

简单地说:

  • 如果你需要做的事情(一个过程,当你不需要捕获每个调用的返回值),只有当选项被定义(即是一个):使用foreach (如果你关心每个调用的结果,使用map

  • 如果你需要做的事情,如果选项定义和其他东西,如果不是:在if语句中使用isDefined

  • 如果选项是Some ,则需要该值;如果是None ,则需要默认值:use getOrElse

试图用get来执行我们的操作是更加迫切的风格,在这里你需要打电话做什么和怎么做 。 换句话说,我们正在口述事情,并深入挖掘Options内部。 map,flatmap作为map,flatmap在我们说的是做什么而不是做什么的情况下map,flatmap更有function性。