Scala中的嵌套模式与扁平模式匹配



假设我在Scala中有n值,名为v1v2vivn类型Tij对于不同的i不一定是不同的类型。我想使用自定义逻辑对n值进行模式匹配。

一种方法是嵌套所有可能性,以防我需要穷举(为了这个例子,我需要穷竭,否则我可以使用占位符mag_c),并且我不能合并分支(为了这个示例,我不能,因为每个自定义逻辑都是唯一的):

v1 match {
case x1: T11 => v2 match {
case x2: T21 => v3 match {
...
case xn_1: Tn_11 => vn match {
case xn: Tn1 => // Custom logic 1.
case xn: Tn2 => // Custom logic 2.
...
case xn: Tnk => // I am already laughing, but I have to write it down: 
// Custom logic k.
}
...     
...
}
case x2: T22 => v3 match {
// I guess you get the point. 
}
...
case x1: T12 => v2 match {
// And so on until exhaustion in every meaning of the word.
}
... // These three dots are needed here. Now I feel whole.      
}

另一种选择是将整个该死的东西压平:

(v1, v2, ..., vn) match {
case (x1: T11, x2: T21, ... xn: Tn1) => // Custom logic 1.
case (x1: T11, x2: T21, ... xn: Tn2) => // Custom logic 1.
...
case (x1: T11, x2: T21, ... xn: Tnk) => // Custom logic k (with a hearthy chuckle).
... // Three dots saving my soul and my finger joints.
}

虽然嵌套版本避免了重复键入,但当n为高时(我们不是),由于缩进溢出,它可能会导致代码难以读取。

另一方面,扁平化版本包含大量重复代码,但更易于解释。

此外,嵌套版本似乎更具性能,因为xi的检查每个类型最多发生一次Tij(但也许我不应该关心这样的事情,因为JVM可以完全优化它,我不想万恶)。

哪一个是惯用的Scala代码,因此推荐使用?这两个版本的性能有什么不同吗?

您应该选择最能表达代码含义的选项,而不必担心性能问题。如果这个match的性能对您的代码至关重要,那么您的设计就会遇到更大的问题。(也不清楚其中一个的表现是否比另一个好,因此根据假设的表现进行选择是不明智的)。

如果每个case都导致一段独立的代码,那么拥有一个平面match是逻辑的最直接表达。添加虚假的嵌套只会让事情变得混乱。

如果两个或多个case表达式之间有一些公共代码,则可以将它们分组到嵌套的match语句中,这样公共代码就不会重复。如果您希望在代码中表达的多个案例之间存在某种逻辑共性,这也可能适用。

另外请注意,您可以使用orElse链接部分函数,这允许您将一个大的match拆分为具有有意义名称的单独函数,同时避免嵌套的match语句。

最新更新