简体   繁体   English

在Scala中使用Either进行错误处理

[英]Error handling with Either in Scala

This is a followup to my previous question . 这是我先前问题的跟进。 Suppose I have the following functions: 假设我具有以下功能:

type Result[A] = Either[String, A] // left is an error message

def f1(a: A): Result[B] = ...
def f2(b: B): Result[C] = ...
def f3(c: C): Result[D] = ...

def f(a: A): Result[D] = for {
  b <- f1(a).right
  c <- f2(b).right
  d <- f3(c).right
} yield d; 

Suppose also I would like to add more information to the error message. 假设我还要向错误消息添加更多信息。

 def f(a: A): Result[D] = for {
  b <- { val r = f1(a); r.left.map(_ + s"failed with $a"); r.right }
  c <- { val r = f2(b); r.left.map(_ + s"failed with $a and $b"); r.right }
  d <- { val r = f3(c); r.left.map(_ + s"failed with $a, $b, and $c"); r.right } 
} yield d; 

The code looks ugly. 该代码看起来很难看。 How would you suggest improve the code ? 您如何建议改进代码?

The code looks ugly because you're repeating yourself. 该代码看起来很难看,因为您要重复自己。

Write a method instead! 写一个方法代替! Or an extension method. 或扩展方法。 One of these, maybe: 其中之一,也许是:

implicit class StringEitherCanAdd[A](private val e: Either[String, A]) extends AnyVal {
  def info(s: String): Either[String, A] = e.left.map(_ + s)
  def failed(a: Any*): Either[String, A] =
    if (a.length == 0) e
    else if (a.length == 1) e.left.map(_ + s"failed with ${a(0)}")
    else if (a.length == 2) e.left.map(_ + s"failed with ${a(0)} and ${a(1)}")
    else e.left.map(_ + s"failed with ${a.init.mkString(", ")}, and ${a.last}")
}

Now you just 现在你

f1(a).info(s"failed with $a").right
f2(b).failed(a,b).right

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM