假设我为Scala应用程序定义了错误。我希望它们是Error
,Warning
和Ok
。我希望Error
和Warning
包含人类可读的短信。
我还要分配数字代码(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)) }
有意义吗?你会如何实现它?
答案 0 :(得分:8)
根据我的几个问题:
sealed trait
或简单的abstract class
MyErrors
对象中?Int
字段吗?您可以使用模式匹配进行过滤。Ok
作为MyError
的实例看起来在语义上是错误的。我宁愿使用Status
ErroneousStatus
Either
或Validation
?答案 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