我希望能够传递“无”的可选原因。我试着将'无'扩展为:
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或其他东西,但这似乎很难维护。什么是一种优雅的解决方法?
答案 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.")
}
如果您发现它有太多样板,您可以使用ScalaUtils或Scalaz或任何其他具有Option-with-reason替代品的库。 ScalaUtils非常容易快速上手。 Scalaz要深得多,如果你需要深度很棒,如果你不需要,那就意味着需要更长时间才能开始工作。
答案 1 :(得分:0)
None不是null的别名。它是一个对象(单例),它扩展了Option [Nothing]
你不能扩展它的原因是Option是密封类,这意味着它只能由与密封类相同的文件中的类扩展。
正如李在你的问题的评论中写道,要走的路是使用Try[T]
或Either[String, T]
。
Here关于如何使用它们的一些很好的解释。