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

时间:2019-01-22 09:35:59

标签: scala nested pattern-matching flatten

假设我在Scala中有 n 个值,分别为 v 1 v 2 < / strong>,..., v i ,..., v n T ij 对于不同的 i 不一定是不同的类型。我想使用自定义逻辑对 n 值进行模式匹配。

一种方法是嵌套所有可能性,以防万一我需要穷举(出于本例的需要,否则,我可以使用占位符mag _ c),并且我可以t合并分支(由于每个自定义逻辑都是唯一的,因此在此示例中我不能这样做):

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 为高(而我们不是)时,由于缩进溢出,可能导致难以阅读的代码。

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

此外,嵌套版本似乎更有效,因为对 x i 的每种类型的 T ij 检查一次最多(但是也许我不应该在意JVM可以完全优化它,而我不想成为all evil)。

哪个是惯用的Scala代码,因此建议使用?两种版本之间在性能上有区别吗?

1 个答案:

答案 0 :(得分:2)

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

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

如果两个或多个case表达式之间存在一些通用代码,则可以将它们分组为嵌套的match语句,以使通用代码不会重复。如果要在代码中表达的多个情况之间存在某种逻辑上的共通性,则这也可能适用。

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