Scala和Java选项如果存在则执行,如果不执行其他操作则执行

Scala和Java选项如果存在则执行,如果不执行其他操作则执行,java,scala,optional,Java,Scala,Optional,scala和java中的选项是我很难理解和使用的。我理解它的存在是为了消除“空”处理地狱。坦白地说,我认为这是另一种地狱 我在java中处理空值的方法是: String test = null; if(test==null) // do something else // do something else 当我切换到选项时,这种决定就是我想要做的 但是scala和java中的Option类中都没有方法可以说,如果null为do something,则else为do something 有一

scala和java中的选项是我很难理解和使用的。我理解它的存在是为了消除“空”处理地狱。坦白地说,我认为这是另一种地狱

我在java中处理空值的方法是:

String test = null;
if(test==null) // do something
else  // do something else
当我切换到选项时,这种决定就是我想要做的

但是scala和java中的Option类中都没有方法可以说,如果null为do something,则else为do something

有一种方法可以在subject为null时默认值,例如

//in scala
test.getOrElse("defaulted")
我想知道为什么不能有像我写的“拉皮条”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)
}

相反,我被迫编写match和case来处理与选项有关的任何事情。我一定是做错了什么。最有可能的是,我对如何使用选项的理解存在缺陷。由于某种原因,上述处理方式默认不在Option类中。现在,这可能是什么原因呢?

我认为你缺少的是你需要选择的原因

选项(以及Java中的选项)背后的思想是您(开发人员)现在可以声明在类型级别上可能存在或不存在值

花点时间考虑一下。对于一个可能为null的变量,您将如何做到这一点

这是个问题,对吗

  • 当您读取该值时,您不知道它是否会为null
  • 如果希望代码安全,则必须始终使用此类变量检查它是否为null
但是,现在,使用Options/Optionals,编译器会告诉您和使用您的代码的其他开发人员他们必须检查该变量是否为null(或不为null!)

如果我们现在更进一步,想象一下,如果您以任何可能为null的变量都是选项的方式编写所有代码。任何永远不会为空的变量(总是有一个值)都不是空的!你现在明白我的意思了吧


如果您像这样编写所有代码,您将永远不会意外地依赖不存在的值的存在,也不会对值是否存在进行不必要的检查,而它总是存在的!;)

在scala中,有几种方法可以实现这一点:

  • optValue.map(successFunction).getOrElse(errorFunction)
  • optValue.fold(errorFunction)(successFunction)
也许你想要的是第二个,
fold

java中有一个
.map
,不确定是否有
.fold
,您需要查看

编辑: 当您要求在折叠中添加换行符时,请尝试使用括号:


使用
Any
作为方法(或方法参数)的类型会将您带入真正的地狱(您将失去类型系统为您提供的所有功能)。也就是说,使用
选项
实例最惯用的方法是将其视为一个集合或monad,并使用
映射
平面映射
过滤器
foreach
。向下滚动至“如果值存在,则执行某些操作”…Scala已经有了
折叠
来执行此操作:
测试.fold(addError(“未找到”))(builder++=\ucode>您缺少OP的要点。我想他明白这一点。但他想在没有选择的情况下做点什么,这并非不合理。Map etc允许您在选项为“某些”时执行某些操作(无选项时不执行任何操作),但如果在选项为“无”时确实要执行某些特定操作(例如,显示错误消息),则不太受支持。我的回答基于他的回答:“我一定是做错了什么。很可能,我对如何使用选项的理解存在缺陷。”Comments仍然没有回答他的实际问题,这是关于处理None案件的问题(参见主题行和最后的问题),谢谢。以这种方式使用map方法看起来也很有用。使用fold方法,我不能将fold(…)(…)写入fold\n(…)\n(…)吗?从某种意义上讲,为了便于阅读,在折叠后和每个括号后放一行新行。我的IDE显示为错误。请尝试使用大括号{}:
Some(2)。折叠{println(“错误”)}{value=>println(s“Success:$value”)}
Some(2).fold
  {
    println("error")
  }
  {
    value =>
      println(s"Success: $value")
  }