Scala Some,None 和我的自定义默认值

Scala Some, None and my custom Default

我们在 Scala 中有一些 None,我需要第三个名为 Default 的。 背后的想法是:

我不想用我的自定义类型完全“隐藏”Some,None。我想让用户使用它们并在某些情况下应用我自己的“默认值”。

@Michael Zajac 给了几个选项,我觉得第一个不错

我可以内置一些,None 和“人工”,如

case object DefaultParamHere {
    def apply(): Option[String] = {
      Some("Substitute me we default framework value, please")
    }
  }

谢谢!

所以用例将是:

case class Application(artifact: Artifact,
                              mainClass: Class[_],
                              jvmMemory: Option[Memory] = None,
                              jvmOpts: Option[String] = DefaultParamHere(),
                              applicationConfiguration: List[String] = Nil) extends Stage

您确实有多种选择。你可以:

使用标记值。 例如,如果您使用 Option[Int]Some(-1) 可以编码 "default" 但不能None 值。客户端代码需要知道这个值需要特殊处理,这使得这个解决方案很薄弱。它很容易实现,但对于那些需要使用 returns 标记值的代码的人来说很难。我不推荐这种方法。

使用不同的类型,例如Option[Either[Default, B]]。在此解决方案中,Some(Right(a)) 表示现有值,Some(Left(Default)) 表示您的特殊情况,None 仍然表示完全缺少数据。 Default 可以像表示您需要做某事的 case 对象一样简单,也可以像包含程序可能需要处理的默认值的某种数据类型一样简单。在我看来,这是最好的选择(一语双关),因为它清楚地表明返回此类型时方法可能会返回什么,并强制代码处理 Default案例.

使用不同的类型,例如Option[Option[A]]。这里 Some(Some(a)) 代表现有值,Some(None) 代表您的特殊情况,None 与以前相同。这与之前的解决方案相似,除了没有办法在默认情况下对附加信息进行编码,而且关于返回此方法的方法会更加神秘类型实际上是为了。

使用不同的类型,例如scalaz.Either3。与前两个解决方案类似,您可以使用 Either3[None, Default, A] 对三个案例进行编码,其中 Right3(a)Middle3(Default)Left3(None) 是各自的案例。这将再次明确类型的用途,并强制客户端代码处理所有三种情况。但是,对于您需要的东西来说,这可能有点矫枉过正。尽管如此,如果您想在 None 案例中编码更多信息,Either3 总是在那里。

使用包装器。如果不了解更多关于您的用例,很难准确地说出这会是什么样子,但您可以做一个简单的 class包装 Option 并可以提供您想要的默认值。

case class Option3[A](opt: Option[A], default: A) {
  def getOrDefault: A = opt.getOrElse(default)
}

当然,这可能不是您真正想要的,而是符合这些思路的。您还可以提供从包装器到 Option 的隐式转换,它可以在 None 情况下替换默认值,否则取决于您真正想要它做什么。