Scala:左右匹配,左右返回,而无需解开对象



我有一个用例,我想返回左的未来。当我得到那个未包装并再次创建的地方:

fooEither match {
    case Right(value) => //.. Some logic. returns Future(Right(MyObj))
    case Left(value) => Future(Left(value))
}

我想在第二种情况下再次摆脱对象创建。类似:

fooEither match {
    case Right(value) => //.. Some logic. returns Future(Right(MyObj))
    case left: Left(_) => Future(left)
}

它给了我类型不匹配的汇编错误。

问题是Left携带Either超级类型的两个类型参数:

trait Foo; trait Bar; trait Quux
import scala.concurrent.Future
def test(e: Either[Foo, Bar]): Future[Either[Foo, Quux]] = e match {
  case Right(bar) => Future.successful(Right(new Quux {}))
  case left: Left[Foo, Bar] => Future.successful(left) // XXX
}

这不会编译,因为在// XXX中,您尝试返回Future[Either[Foo, Bar]]。但是,以下作品:

def test(e: Either[Foo, Bar]): Future[Either[Foo, Quux]] = e match {
  case Right(bar) => Future.successful(Right(new Quux {}))
  case left: Left[Foo, Nothing] => Future.successful(left)
}

尽管编译器发出警告:

warning: non-variable type argument Nothing in type pattern scala.util.Left[Foo,Nothing] (the underlying of Left[Foo,Nothing]) is unchecked since it is eliminated by erasure
     case left: Left[Foo, Nothing] => Future.successful(left)
                ^

这是"安全的",因为您永远无法从Left获得第二类参数的元素,但它是"肮脏"的,好像您会将左投向Left[Foo, Quux]。我建议重建Left,然后通过推理获得正确的类型。

我宁愿使用模式绑定器,而不是再现Either类型的完整类型参数,例如:

case left @ Left(_) => Future.successful(left)

最新更新