scala和java中的选项是我难以理解和使用的东西。我理解它的存在是为了消除' null'处理地狱。坦率地说,我认为它引入了另一种地狱!
我在java中处理null的方法是做类似的事情:
String test = null;
if(test==null) // do something
else // do something else
当我切换到选项时,我正在寻求做出这种决定。
但是scala和java中的Option类中没有方法可以说,如果null执行某些操作,则执行其他操作。
如果主题为空,有一种方法可以默认值,例如
//in scala
test.getOrElse("defaulted")
我想知道为什么不能使用像我写的那样的隐式课程' pimp up' Scala选项
object Definitions{
implicit class OptionExtensions[$Data](option: Option[$Data]){
def perform (found: ($Data)=>Any, notFound: ()=>Any): Any={
option match{
case Some(data)=> found(data)
case None=> notFound()
}
}
}
}
请忽略命名错误的方法。但是现在写了这个,我可以使用这样的选项:
import Definitions._
val test : Option[String] = None
var builder =new StringBuilder
test.perform(builder ++= _, ()=>addError("not found"))
//or
println(test.perform(_.reverse, ()=>{"something else"}))
def addError(error:String)={
println(error)
}
相反,我被迫编写匹配和案例来处理与Options有关的任何事情。我一定做错了什么。最有可能的是,我对如何使用选项的理解是有缺陷的。由于某种原因,上面的处理方式默认不在Option类中。那可能是什么原因?
答案 0 :(得分:8)
在scala中,有几种方法可以实现这一目标:
optValue.map(successFunction).getOrElse(errorFunction)
optValue.fold(errorFunction)(successFunction)
可能你想要的是第二个,fold
。
在java中有.map
,不确定是否有.fold
,您需要查看the docs
编辑: 当您要求在折叠中添加换行符时,请尝试使用括号:
Some(2).fold
{
println("error")
}
{
value =>
println(s"Success: $value")
}
答案 1 :(得分:1)
我认为您缺少的是为什么您需要选项的原因。
选项(和Java中的Optionals)背后的想法是,你(开发人员)现在可以声明值可能存在或不存在,类型级别。
花点时间考虑一下。你怎么能用一个可能只是null的变量呢?
...
这是一个问题,对吧?
但是,现在,使用选项/可选项,您和其他一些使用您的代码的开发人员现在被编译器告知他们必须检查这可能性变量将为null(或不是!)。
如果我们现在更进一步,想象一下,如果以一种任何可能为null的变量为Option的方式编写所有代码。任何永远不会为null的变量(总是有一个值)都不是!你现在明白我的意思吧?
如果你写下这样的所有代码,你最终将不会意外地依赖不存在的价值,也不会对价值是否存在进行不必要的检查,当它始终存在时! ; )