我有一个用例,我想返回左的未来。当我得到那个未包装并再次创建的地方:
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)