在函数式编程中,您可以避免抛出异常,这意味着函数返回值是放置错误消息的逻辑位置(即在电信行话中,错误消息是带内的。)这对于分布式编程特别有用(例如演员) ),但我发现它在其他情况下很有用。
特别是,我正在编写一个通过模板发送电子邮件的课程,如果事实证明,我不想打扰记录小问题(例如,收件人的姓名丢失)存在更大的问题(例如,丢失电子邮件地址,或者某些不方便检查的高级业务规则。)
另一种说法是我希望将错误/警告处理与执行堆栈分离。我不想首先被迫检查最严重的错误,也不想假设他们在同一个帖子中被检查。
我从这样的事情开始,每个邮件模板的实现方式都不同。 MessageInfo是用于填充模板的数据,它是每个模板的不同子类。
trait MessageInfoSource {
def messageInfo(recipient : Person) : Option(MessageInfo)
}
当我实现它时,我可以更明确地看待我想要的MessageInfo类型。但是,如果出现问题,我会得到一个无,而不是一个理由。 (如果我用Java方式做的话,我会抛出一个未经检查的异常;可能是一个NullPointerException,可能装饰了我想要的所有调试信息。)
所以我写了这个:
sealed trait MessageInfoOption extends Iterable[MessageInfo]
case class SomeMessageInfo(messageInfo : MessageInfo) extends MessageInfoOption {
override def iterator = Some(messageInfo).iterator
}
case class NoMessageInfo(reason : String, debugInfo : Map[String, _ <: AnyRef] = Map.empty) extends MessageInfoOption {
override def iterator = None.iterator
}
如果我决定想要,我可以为SomeMessageInfo添加一个警告容器。
这样做的缺点是它与特定的类(MessageInfo)绑定,当我尝试将其更改为更通用的类型(例如[M&lt;:MessageInfo])时,我最终会在Scala&#中39;仿制药和协变量的迷宫。
查看Option的源代码没有帮助 - 我想要一些简单的东西,因为我打算在整个地方使用这个模式
我现在的解决方案是使用后者,并在打开包装时输入。但我对此并不满意。
Scala中是否存在一些预先存在的库或简单的设计模式,可以作为Option的替代提供,以提供更详细的错误处理?