很多嵌套匹配...模式匹配的情况

Ala*_*ano 8 scala

我有一个自动生成的Web服务客户端.我有很多复杂的类,我必须对它进行模式匹配.现在我的结构看起来像这样:

val response = client.getResponse
response match {
  case Left(_) => None
  case Right(a: SomeClass) => a match {

    case SomeClass2(b: Option[SomeClass3]) => b match {

      case None => None
      case Some(c: SomeClass3) => c match {

        case SomeClass4(_, _, _, _, d: Seq[SomeClass4]) => d match {
          case Nil => None

          case seq: Seq[SomeClass5] => seq match {
            case Nil => None
            case Seq(xs@_*) => xs map { x =>
              x match {
                case Nil => None

                case SomeClass6(e: SomeClass7) => e match {
                  case Nil => None

                   case SomeClass8(f, _, _, _, _) => f match {
                    case Nil => None
                    case Seq(xs@_*) => xs map { x => 
                      x match {

                        case Nil => None
                        case SomeClass9(g: Seq[SomeClass9], _, _, _, _, _, _, _, _, _, _) => /* + some nested levels more*/
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

这里SomeClass1 - SomeClass9case类.

如你所见,它似乎令人恐惧.我该怎么办?什么是让它看起来更好的标准方法?

我想不仅应该重构而是另一种方法.

sen*_*nia 7

假设a应该是SomeClass2,但不是SomeClass(与相同b,c,d).

您可以使用替代模式,如case A | B => ...结构模式Some(MyClass(f)).

此外,你可以在使用部分功能map类似map { case ... }的代替map { x => x match {...} }.

我想你的代码中有一个错误:有检查case Nil => ...; case SomeClass8(...) => ....

你可以替换Seq(xs @_*)使用xs.如果您需要整个集合,则无需提取元素.

你的代码:

response match {
  case Left(_) | Right(SomeClass2(None)) | Right(SomeClass2(Some(SomeClass3(_, _, _, _, Nil))) => None
  case Right(SomeClass2(Some(SomeClass3(_, _, _, _, xs))) =>
    xs map {
      case SomeClass6(None) | SomeClass6(Some(SomeClass8(Nil, _, _, _, _))) => None
      case SomeClass6(Some(SomeClass8(xs, _, _, _, _))) =>
        xs map {
          case Nil => None
          case SomeClass9(g, _, _, _, _, _, _, _, _, _, _) => /* + some nested levels more*/
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

您还应该将嵌套匹配提取到单独的方法中.

模式匹配不是唯一的解决方案.你可以使用Either和的方法Option:

response.right.toOption.collect {
  // No need for the first part.
  case SomeClass2(Some(SomeClass3(_, _, _, _, xs)) if xs.nonEmpty => ...
}
Run Code Online (Sandbox Code Playgroud)


Thi*_*Tim 5

您可能会发现提取器很有用.也许有些情况可能会让一些案件变得扁平化

case Right(SomeClass(SomeClass2(Some(SomeClass3(value))))) => value ...
case _ => None
Run Code Online (Sandbox Code Playgroud)

而不是None在每个级别明确定义一个案例.

  • 并且创建一些包含内部匹配语句的标准辅助函数显然也会减少疯狂的嵌套. (3认同)