Scala 执行条件转换的惯用方法

Scala 执行条件转换的惯用方法,scala,Scala,我有一个对象x。我将对它执行一系列转换。这可以很容易地表示为 x.transformA.transformB.transformC 然而,在每次转换之前,我还应该检查一个条件。只有当条件为true时,我才能执行转换。我有两种表达方式。第一个是将x定义为一个var var x = anObject if (x.condA) x = x.transformA if (x.condB) x = x.transformB if (x.condC) x = x.transformC // final r

我有一个对象
x
。我将对它执行一系列转换。这可以很容易地表示为

x.transformA.transformB.transformC
然而,在每次转换之前,我还应该检查一个条件。只有当条件为true时,我才能执行转换。我有两种表达方式。第一个是将x定义为一个var

var x = anObject
if (x.condA) x = x.transformA
if (x.condB) x = x.transformB
if (x.condC) x = x.transformC
// final result in x
或者,为了避免var,我定义了一系列中间变量

val x0 = anObject
val x1 = if (x0.condA) x0.transformA else x0
val x2 = if (x1.condB) x1.transformB else x1
val x3 = if (x2.condC) x2.transformC else x2
// final result in x3

这似乎相当麻烦,甚至在我剪切和粘贴行时也容易出错。有没有更惯用的方式来表达这一点?

可以将一系列条件转换表示为函数的组合。这样,每个转换都可以独立声明,并重用以构建新的转换

例如:

val ta: MyClass => MyClass = {case x if x.condA => x.transformA
                              case x => x}
val tb: MyClass => MyClass = {case x if x.condB => x.transformB
                              case x => x}
val tc: MyClass => MyClass = {case x if x.condC => x.transformC
                              case x => x}
然后,我们可以将这些组成我们的转换:

val transformation = ta andThen tb andThen tc
val transformedObj =  transformation(x)
我们可以在上面看到,我们正在一次又一次地重复相同的模式。为了避免这种情况,我们可以创建一个创建部分函数的函数,减少样板代码:

def mkTf[T](cond: T => Boolean, transf: T => T): T => T = {
  case x if cond(x) => transf(x)
  case x => x
}
然后我们可以将我们的作文改写为:

val transformation = mkTf[MyClass](_.condA,_.transformA) andThen
                     mkTf[MyClass](_.condB,_.transformB) andThen
                     mkTf[MyClass](_.condC,_.transformC)

对象的类型永远不会改变?从上面的表达式中可以看出,
xi.transform
xi
是同一类型的。折叠怎么样?需要什么
PartialFunction
s
Function
在这里工作得很好,因为它是为每个
x:T
@cyrilecorpet定义的,您完全正确。我开始用添加身份案例作为
PartialFunction
回退(
orElse
)的想法来回答问题,但后来又有了另一个想法。相应地修改了答案。谢谢,谢谢!它使我免于拥有一堆中间变量。