如何在Scala中定义错误类型?
假设我为Scala应用程序定义了错误。我希望它们是如何在Scala中定义错误类型?,scala,enums,Scala,Enums,假设我为Scala应用程序定义了错误。我希望它们是错误、警告和正常。我希望错误和警告包含人类可读的文本消息 我还想分配数字代码(0-表示Ok,1-表示Warning,2-表示Error),例如,在错误列表中查找最严重的错误 因此,我将这个错误定义如下: object MyErrors { abstract sealed case class MyError(code: Int, maybeMessage: Option[String]) object Ok extends MyErr
错误
、警告
和正常
。我希望错误
和警告
包含人类可读的文本消息
我还想分配数字代码(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))
}
对象MyErrors{
抽象密封案例类MyError(代码:Int,maybeMessage:Option[String])
对象Ok扩展MyError(0,无)
最终案例类警告(消息)扩展了MyError(1,部分(消息))
最后一个案例类错误(消息)扩展了MyError(2,Some(消息))
}
这有意义吗?您将如何实施它?我认为有几个问题:
MyErrors
对象中Int
字段吗?您可以使用模式匹配进行过滤Ok
作为MyError
的实例在语义上看起来是错误的。我宁愿使用状态
errorstatus
这就是我认为你想要做的:
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)
很明显,它可以被清理很多。但是它应该会让你继续前进。根据Nicolas关于将你的类型重命名为
状态的建议,这里有一些代码和其他细节:
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
是(2*警告==错误)
?:)如果不是,则算术数据类型的概念有点过于具体。也许像日志记录这样的粗略分组(严重、严重、致命等)更好,并且可以通过继承来建模。另外:类或可能对您有用。之后,如果他有更多错误值,则可能会有用。。。例如,要使用大于x
的代码过滤每个错误。请查看Scala的解析器组合器如何对结果进行编码,这些结果具有类似的层次结构。@Nicolas最好删除数字代码,而使用排序/排序。@paradigmatic我完全同意。我只需要弄清楚如何添加排序
.Re:5,这样它就不再是代数类型了。@missingfakt或不需要:密封特征状态
-密封特征错误状态扩展状态
-然后对象
/案例类
es…@Nicolas:虽然你的批评是有效的,这不是问题的答案。@Nicolas,是的,这不是ADT。