Scala Either:获取左右存在的 属性 的最简单方法

Scala Either : simplest way to get a property that exists on right and left

我有一个使用 valueObject 的模板,它可能是两种风格之一,具体取决于它在我们的应用程序中的使用位置。所以我将其作为 Either 导入:

valueObject: Either[ ObjectA, ObjectB ]

两个对象都有一个同名的 属性,所以我想通过调用

来检索它
valueObject.propertyA

这是行不通的。

最简洁/最好的方法是什么?

假设这两个对象具有定义 属性 的相同类型(或超类型/特征) - 您可以使用 merge,如果 returns 存在则左边,否则右边,两者的最低常见类型:

scala> class MyClass {
 | def propertyA = 1
 | }
defined class MyClass

scala> val e1: Either[MyClass, MyClass] = Left(new MyClass)
e1: Either[MyClass,MyClass] = Left(MyClass@1e51abf)

scala> val e2: Either[MyClass, MyClass] = Right(new MyClass)
e2: Either[MyClass,MyClass] = Right(MyClass@b4c6d0)

scala> e1.merge.propertyA
res0: Int = 1

scala> e2.merge.propertyA
res1: Int = 1

使用fold

假设这两个对象不共享包含 property/method 的公共超类型,那么您必须求助于 fold:

scala> case class A(a: Int)
defined class A

scala> case class B(a: Int)
defined class B

scala> def foldAB(eab: Either[A,B]): Int = eab.fold(_.a,_.a)
foldAB: (eab: Either[A,B])Int
   
scala> foldAB(Left(A(1)))
res1: Int = 1

scala> foldAB(Right(B(1)))
res2: Int = 1

模式匹配

另一种可能是使用模式匹配:

scala> def matchAB(eab: Either[A,B]): Int = eab match { case Left(A(i)) => i; case Right(B(i)) => i}
matchAB: (eab: Either[A,B])Int

scala> matchAB(Left(A(1)))
res3: Int = 1

scala> matchAB(Right(B(1)))
res4: Int = 1