简体   繁体   中英

What is the difference between this two following cases of pattern matching in scala

sealed trait User
case class ExternalUser(name: String, email: String) extends User
case class InternalUser(tag: String, email: String) extends User

val user: User = ...

user match {
  case u: ExternalUser => 
    println(s"${u.name}")

  case InternalUser(tag, email) => 
    println(s"${tag}")
}

When should I use one as oppose to the other and why.

When it comes to case classes, both can be used interchangeably.

If you prefer to have a reference to the matched ExternalUser value itself, then first approach makes more sense, because you can refer to it via u .

If you prefer to unapply the whole case class into its parts (tag, email etc.), then second approach makes more sense, because you don't have to keep selecting them via u .

If you prefer to use the second approach, but you still want to hold a reference to the whole case class, you can also do:

case u @ InternalUser(tag, email) => 
  println(s"$u $tag $email")

They're quite similar. The second form allows you to do recursive pattern matching, so instead of just binding variable names you can also deconstruct the parts further:

val G = "(.*)@gmail.com".r
user match {
  case InternalUser(tag, G(localPart)) =>
    // handle internal users with Gmail address here
  ...
}

The first form has the advantage that you don't need to list all the fields. This is useful for case classes with many fields that aren't relevant in this context, or if you expect the case class to gain additional fields in the future – you then don't have to change this match expression to go along with it.

ExternalUser can be a trait , class , or case class . The member element name can be any publicly available element by that name. It doesn't have to be a constructor argument.

InternalUser(a,b) must have it's own unapply() method, which a case class automatically supplies. The unapply() method will populate the local identifiers, a and b in this case. If the unapply() method is the default supplied by the case class then the local identifiers will have a 1-to-1 correspondence with the case class constructor arguments.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM