我们在Scala中有一些,没有,我需要名为Default的第三个。 背后的想法是:
默认(我的自定义事物)意味着用户希望我应用一些内置的默认值。
它应该像None一样(即与Option兼容),并且我将在我的例程中以特殊方式处理Default。 我看了一眼:Scala: Something like Option (Some, None) but with three states: Some, None, Unknown
我不想完全"影子"一些,没有我的自定义类型。我希望让用户使用它们并应用我自己的"默认"在某些情况下。
@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
答案 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)
}
个案例中的默认值,或者取决于您真正希望它做什么。