Reputation: 137
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.
Upvotes: 2
Views: 81
Reputation: 9698
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")
Upvotes: 8
Reputation: 4587
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.
Upvotes: 3
Reputation: 51271
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.
Upvotes: 1