Scala Some,None 和我的自定义默认值
Scala Some, None and my custom Default
我们在 Scala 中有一些 None,我需要第三个名为 Default 的。
背后的想法是:
Some表示有一定的价值
None表示完全没有值。不使用值。
默认(我的自定义设置)表示用户希望我应用一些内置默认值。
它应该像 None 一样(即与 Option 兼容),我将在我的例程中以特殊方式处理 Default。
我看了看:Scala: Something like Option (Some, None) but with three states: Some, None, Unknown
我不想用我的自定义类型完全“隐藏”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
情况下替换默认值,否则取决于您真正想要它做什么。
我们在 Scala 中有一些 None,我需要第三个名为 Default 的。 背后的想法是:
Some表示有一定的价值
None表示完全没有值。不使用值。
默认(我的自定义设置)表示用户希望我应用一些内置默认值。
它应该像 None 一样(即与 Option 兼容),我将在我的例程中以特殊方式处理 Default。 我看了看:Scala: Something like Option (Some, None) but with three states: Some, None, Unknown
我不想用我的自定义类型完全“隐藏”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
情况下替换默认值,否则取决于您真正想要它做什么。