代码之家  ›  专栏  ›  技术社区  ›  Avba

scala语法匹配多个case类类型而不分解case类[duplicate]

  •  3
  • Avba  · 技术社区  · 6 年前

    我对各种case类实现有一个封闭的特性。我想对同一个匹配表达式同时对多个类进行模式匹配。如果不分解case类和它们之间的“|”,我似乎无法做到这一点

    当前看起来像:

    sealed trait MyTrait {
      val param1: String
      ...
      val param100: String
    }
    
    case class FirstCase(param1: String ...... param100: String) extends MyTrait
    ...
    case class NthCase(param1: String ..... param100: String) extends MyTrait
    

    def myFunction(something: MyTrait) = {
       ...
       val matchedThing = something match {
          // this doesn't work with "|" character
          case thing: FirstCase | SecondCase => thing.param1
          ...
          case thing: XthCase | JthCase => thing.param10
       }
    } 
    
    2 回复  |  直到 6 年前
        1
  •  8
  •   stefanobaghino    6 年前

    让我们一步一步地去那里:

    1. 这个 | 运算符,在模式匹配的上下文中,允许您定义可选的 模式 ,格式如下:

      pattern1 | pattern2
      
    2. binding: Type
      
    3. 在两种不同类型之间提供选择,应以以下形式提供:

      binding1: Type1 | binding2: Type2
      
    4. 要将单个名称绑定到两个可选绑定,可以放弃单个绑定的名称(使用 _ 通配符)并使用 @ 运算符,如下例所示:

      binding @ (_ : Type1 | _ : Type2)
      

    sealed trait Trait {
      def a: String
      def b: String
    }
    
    final case class C1(a: String, b: String) extends Trait
    final case class C2(a: String, b: String) extends Trait
    final case class C3(a: String, b: String) extends Trait
    
    object Trait {
      def f(t: Trait): String =
       t match {
        case x @ (_ : C1 | _ : C2) => x.a // the line you are probably interested in
        case y: C3 => y.b
      }
    }
    

    f :

    scala> Trait.f(C1("hello", "world"))
    res0: String = hello
    
    scala> Trait.f(C2("hello", "world"))
    res1: String = hello
    
    scala> Trait.f(C3("hello", "world"))
    res2: String = world
    

    你可以玩弄下面的例子 here on Scastie

        2
  •  1
  •   Yaneeve    6 年前

    这对我有用 https://scastie.scala-lang.org/pT4euWh6TFukqiuPr4T6GA

    sealed trait Sup {
      def a: String
      def i: Int
    }
    
    case class First(a: String, i: Int, d: Double) extends Sup
    
    case class Second(a: String, i: Int, x: Seq[Double]) extends Sup
    
    case class Third(a: String, i: Int, c: Char) extends Sup
    
    val sups = Seq(First("s", 1, 1.0), Second("s", 4, Seq(1.1)), Third("s", 4, 'f'))
    
    sups.foreach {
      case _: First | _: Second => println("ffff")
      case _                    => println("ggg")
    }
    
    推荐文章