为什么foreach比获得Scala选项更好?
为什么使用foreach
, map
, flatMap
等被认为比使用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的选项备忘单 。
将map
, foreach
和flatMap
等东西直接应用到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
也可能是不确定的。 由于get
在None
不起作用,所以你必须做一些额外的工作来确保你没有得到任何的错误。 额外的工作是由你完成的map
。
简单地说:
-
如果你需要做的事情(一个过程,当你不需要捕获每个调用的返回值),只有当选项被定义(即是一个):使用
foreach
(如果你关心每个调用的结果,使用map
) -
如果你需要做的事情,如果选项定义和其他东西,如果不是:在if语句中使用
isDefined
-
如果选项是
Some
,则需要该值;如果是None
,则需要默认值:usegetOrElse
试图用get
来执行我们的操作是更加迫切的风格,在这里你需要打电话做什么和怎么做 。 换句话说,我们正在口述事情,并深入挖掘Options
内部。 map,flatmap
作为map,flatmap
在我们说的是做什么而不是做什么的情况下map,flatmap
更有function性。