如何在Scala中定义错误类型?

时间:2012-06-06 15:06:07

标签: scala enums

假设我为Scala应用程序定义了错误。我希望它们是ErrorWarningOk。我希望ErrorWarning包含人类可读的短信。

我还要分配数字代码(0代表Ok,1代表Warning,2代表Error),以便在错误列表中找到最严重的错误例如。

因此,我将此错误定义如下:

object MyErrors {  
  abstract sealed case class MyError(code: Int, maybeMessage: Option[String])
  object Ok extends MyError(0, None)
  final case class Warning(message) extends MyError(1, Some(message)) 
  final case class Error(message) extends MyError(2, Some(message))
}

有意义吗?你会如何实现它?

3 个答案:

答案 0 :(得分:8)

根据我的几个问题:

  1. 您无法扩展案例类。考虑sealed trait或简单的abstract class
  2. 为什么所有这些都包含在MyErrors对象中?
  3. 你真的需要Int字段吗?您可以使用模式匹配进行过滤。
  4. Ok作为MyError的实例看起来在语义上是错误的。我宁愿使用Status
  5. 选择的问题,但我会为ErroneousStatus
  6. 定义一个子项目
  7. 在您进入设计之前,您是否考虑过EitherValidation

答案 1 :(得分:2)

这就是我认为你想要做的事情:

object MyErrors extends Enumeration {
  val Ok = Value("ok", 0)
  val Warning = Value("warning", 1)
  val Error = Value("error", 2)

  class TypeVal(val name: String, val code: Int) extends Val(nextId, name)

  protected final def Value(name: String, code: Int) = new TypeVal(name, code)

  sealed case class MyError(error: TypeVal, maybeMessage: Option[String])

  def ok(msg: Option[String] = None) = new MyError(Ok, msg)
  def error(msg: Option[String] = None) = new MyError(Error, msg)
  def warning(msg: Option[String] = None) = new MyError(Warning, msg)

}

用作:

val e = MyErrors.error() 
// or
val f = MyErrors.ok(Option("Don't worry, be happy"))
f.error.code // Int = 0
f.maybeMessage // Option[String] = Some(Don't worry, be happy)
显然,可以清理一下。但它应该让你去。

答案 2 :(得分:2)

关于Nicolas将您的类型重命名为Status的建议,这里有一些其他细节的代码:

sealed trait Status {
  def code: Int
}
object Status {
  case object Ok extends Status {
    val code = 0
  }
  sealed trait WithMessage extends Status {
    def message: String
  }
  case class Warning (message: String) extends WithMessage {
    val code = 1
  }
  case class Error (message: String) extends WithMessage {
    val code = 2
  }
}

然后你可以像这样使用它:

scala> Status.Ok
res0: Status.Ok.type = Ok

scala> Status.Warning("blabla")
res1: Status.Warning = Warning(blabla)

scala> Status.Error("blabla").code
res2: Int = 2