在scala中,以下两种模式匹配的情况有什么不同

在scala中,以下两种模式匹配的情况有什么不同,scala,pattern-matching,Scala,Pattern Matching,什么时候我应该使用一个来反对另一个,以及为什么。当涉及到case类时,两者都可以互换使用 如果您希望引用匹配的ExternalUser值本身,那么第一种方法更有意义,因为您可以通过u引用它 如果您喜欢将整个case类取消应用到它的各个部分(标记、电子邮件等),那么第二种方法更有意义,因为您不必一直通过u选择它们 如果您更喜欢使用第二种方法,但仍希望保留对整个案例类的引用,则还可以执行以下操作: sealed trait User case class ExternalUser(name: Str

什么时候我应该使用一个来反对另一个,以及为什么。

当涉及到case类时,两者都可以互换使用

如果您希望引用匹配的
ExternalUser
值本身,那么第一种方法更有意义,因为您可以通过
u
引用它

如果您喜欢将整个case类取消应用到它的各个部分(标记、电子邮件等),那么第二种方法更有意义,因为您不必一直通过
u
选择它们

如果您更喜欢使用第二种方法,但仍希望保留对整个案例类的引用,则还可以执行以下操作:

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}")
}

ExternalUser
可以是
特征
、或
案例类
。成员元素
name
可以是该名称的任何公共可用元素。它不必是构造函数参数


InternalUser(a,b)
必须有自己的
unapply()
方法,由
case类自动提供。
unapply()
方法将填充本地标识符,
a
b
。如果
unapply()
方法是
case类
提供的默认方法,则本地标识符将与
case类
构造函数参数具有1对1的对应关系。

它们非常相似。第二种形式允许您进行递归模式匹配,因此,您不仅可以绑定变量名,还可以进一步解构这些部分:

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

第一个表单的优点是不需要列出所有字段。这对于包含许多与此上下文无关的字段的case类非常有用,或者如果您希望case类将来获得更多字段,则无需更改此
匹配
表达式即可,
InternalUser
的同伴对象必须有自己的
方法。由于使用了
case类
关键字,会自动生成一个,但您始终可以实现自己的“提取器对象”对于您的类型不是特定的
case类
的情况,甚至更具体地说:)名称
InternalUser
必须使用自己的
方法引用对象。它通常是一个类/特征的伴生对象,但不一定是;它甚至可以是一个局部变量。
val G = "(.*)@gmail.com".r
user match {
  case InternalUser(tag, G(localPart)) =>
    // handle internal users with Gmail address here
  ...
}