Skip to content
Search

Scala:PatternMatching

lastmod 2020-10-28created 2020-09-133 edits

Scala has a built-in general pattern matching mechanism. It allows matching on any sort of data with a first-match policy.

Simple example

Here is a small example that shows how to match against an integer value.

object MatchTest1 extends App {
  def matchTest(x: Int): String = x match {
    case 1 => "one"
    case 2 => "two"
    case _ => "many"
  }
  println(matchTest(3))
}

The block with the case statements defines a function which maps integers to strings. The match keyword provides a convenient way of applying a function (like the pattern matching function above) to an object.

Type matching

Here is a second example which matches a value against patterns of different types.

object MatchTest2 extends App {
  def matchTest(x: Any): Any = x match {
    case 1 => "one"
    case "two" => 2
    case y: Int => "scala.Int"
  }
  println(matchTest("two"))
}
  • The first case matches if x refers to the integer value 1.
  • The second case matches if x is equal to the string "two".
  • The third case consists of a typed pattern; it matches against any integer and binds the selector value x to the variable y of type integer.

Scala's pattern matching statement is most useful for matching on algebraic types expressed via case classes. Scala also allows the definition of patterns independently of case classes, using unapply methods in extractor objects.

Tuple matching

  def withoutNull(json: JsValue): JsValue = json match {
    case JsObject(fields) =>
      JsObject(fields.flatMap {
        case (_, JsNull) => None
        case other @ (name, value) => Some(other)
      })
    case other => other
  }

Using guard conditions in matching

    Try(EventQueue.queue.poll(remainMilliseconds, TimeUnit.MILLISECONDS)) match {
      case Success(null) if posodTaskStates != JsNull => Right(JsObject("state" -> posodTaskStates))
      case Success(null) => Left(AnswerCommonError("PosodTaskInfoU.dequeueEvent", Timeout(waitMilliseconds)))
      case Success(content) =>
        Right(withoutNull(JsObject(
          "state" -> posodTaskStates,
          "data" -> content.parseJson
        )))
      case Failure(e) => Left(AnswerCommonError("PosodTaskInfoU.dequeueEvent", CommonUnknown(e.toString)))
    }

Matching the whole object

What if you want to receive the whole object when pattern matching? Use the @ operator in this case.

case class Member(name: String)

object Main extends App {
  val samuel = Member("samuel")
  samuel match {
    case p @ Member(_) => println(p)
    case Member(name) => println(name)
    case _ => println("x")
  }
}

See also

  • Scala
  • Extractor Objects
  • Case Classes

Favorite site

author Zer0 sitemap