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

bug*_*oot 5 scala nested pattern-matching flatten

假设我在Scala中有n个值,类型分别为T ij的 v 1v 2,...,v i,...,v n,它们对于不同的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.      
}
Run Code Online (Sandbox Code Playgroud)

另一个选择是将整个问题弄平:

(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.
}
Run Code Online (Sandbox Code Playgroud)

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

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

而且,嵌套版本似乎更高效,因为每个类型T ijx i的检查最多发生一次(但是也许我不关心JVM可以完全优化它的事情,而且我不想是一切罪恶)。

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

Tim*_*Tim 3

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

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

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

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