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

时间:2016-11-27 16:40:10

标签: scala scala-2.11

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

我不想完全"影子"一些,没有我的自定义类型。我希望让用户使用它们并应用我自己的"默认"在某些情况下。

@Michael Zajac提供了几种选择,我认为第一种选择非常好。

我可以内置Some,None和" artificial"像

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

1 个答案:

答案 0 :(得分:5)

你有几个选择,真的。你可以:

使用哨兵值。例如,如果您正在使用Option[Int]Some(-1)可以编码"默认"但不是None值。客户端代码需要知道这个值需要特别处理,这使得这个解决方案很弱。它易于实现,但对于那些需要使用返回sentinel值的代码的人来说很难实现。我不推荐这种方法。

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

使用其他类型,例如Default。此处Option[Option[A]]代表现有值,Some(Some(a))代表您的特殊情况,Some(None)代表与以前相同。这与以前的解决方案类似,除了在默认情况下没有办法对附加信息进行编码,对于返回此类型的方法实际上是多么神秘一点意思是。

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

使用包装器。如果不了解更多有关用例的信息,很难准确说出这会是什么样子,但是你可以创建一个简单的包装类{{1}并且可以提供你想要的默认值。

Either3

当然,这可能不是你想要的,而是这些方面的东西。您还可以提供从包装器到Option的隐式转换,它可以替换case class Option3[A](opt: Option[A], default: A) { def getOrDefault: A = opt.getOrElse(default) } 个案例中的默认值,或者取决于您真正希望它做什么。