扩展选项w / reason

时间:2014-09-24 21:11:16

标签: scala

我希望能够传递“无”的可选原因。我试着将'无'扩展为:

case class NoneReason(reason: String) extends None

但得到“未找到:输入无”,然后我尝试了:

case class NoneReason(reason: String) extends Option[Nothing] {
    def isEmpty = true
    def get = throw new NoSuchElementException("None.get")
}

但我从密封类选项“

获得”非法继承“

我猜这是一个特例,因为'None'实际上是null或别的别名。

我考虑过复制Option源并将其重命名为TriOption或其他东西,但这似乎很难维护。什么是一种优雅的解决方法?

2 个答案:

答案 0 :(得分:4)

None的可选原因是Either[Option[String], Foo],其中Foo是您的类型。你不能扩展None;它是一个单身人士,因此您可以将其视为null

之类的值

但是Either类可以在两个选项之间进行选择,通过约定的右分支包含“正确”答案(如果一个比另一个更正确)。如果你想要一个可选的错误信息,那就在左侧分支中。因此,您可以切换到上面显示的类型,然后切换到通常使用Option的任何地方,您可以x.right.toOption转换为没有消息的选项,或使用模式匹配或其他,例如。

x match {
  case Right(foo) => useFoo(foo)
  case Left(None) => throw new Exception("Something went wrong.")
  case Left(Some(msg)) => throw new Exception(msg + " went wrong.")
}

如果您发现它有太多样板,您可以使用ScalaUtilsScalaz或任何其他具有Option-with-reason替代品的库。 ScalaUtils非常容易快速上手。 Scalaz要深得多,如果你需要深度很棒,如果你不需要,那就意味着需要更长时间才能开始工作。

答案 1 :(得分:0)

None不是null的别名。它是一个对象(单例),它扩展了Option [Nothing] 你不能扩展它的原因是Option是密封类,这意味着它只能由与密封类相同的文件中的类扩展。
正如李在你的问题的评论中写道,要走的路是使用Try[T]Either[String, T]Here关于如何使用它们的一些很好的解释。

相关问题