如何匹配scala.xml.Elem的未预先定义的apply方法

如何匹配scala.xml.Elem的未预先定义的apply方法,xml,scala,pattern-matching,Xml,Scala,Pattern Matching,要更新xml节点上的子节点,可以执行以下操作(此处缺少其他SO票证参考): 但是,这不起作用,因为它总是在没有显式布尔参数的情况下应用apply方法的解构,因此m总是获取类型节点,并且没有任何匹配 那么如何帮助编译器选择正确的构造函数/应用方法呢?(scala 2.12.1) 不工作: case Elem(p,l,a,s,m:Boolean,child @ _*) case Elem(p,l,a,s,m @(_:Boolean),child @ _*) case Elem(p,l,a,s,m

要更新xml节点上的子节点,可以执行以下操作(此处缺少其他SO票证参考):

但是,这不起作用,因为它总是在没有显式布尔参数的情况下应用apply方法的解构,因此
m
总是获取类型
节点
,并且没有任何匹配

那么如何帮助编译器选择正确的构造函数/应用方法呢?(scala 2.12.1)

不工作:

case Elem(p,l,a,s,m:Boolean,child @ _*)
case Elem(p,l,a,s,m @(_:Boolean),child @ _*) 
case Elem(p,l,a,s,m @Boolean,child @ _*)

所有这些都告诉我,m必须是Node

如果您查看弃用警告,它是伴随对象的apply方法,而不是模式匹配构造函数:

> set scalacOptions += "-deprecation"
> console
scala> import scala.xml._

scala> val node:Elem = <item><category>1</category></item>

scala> node match {
         case Elem(p,l,a,s, child @ _*) ⇒ Elem(p,l,a,s,child.filter(_.label != "category") ++ <category>2</category>:_* )
       }
<console>:17: warning: method apply in object Elem is deprecated: Use the other apply method in this object
  case Elem(p,l,a,s, child @ _*) ⇒ Elem(p,l,a,s,child.filter(_.label != "category") ++ <category>2</category>:_* )
                                   ^
我有点惊讶
Elem
的模式匹配有这个缺陷。由于某种原因,
Elem
在2007年从一个case类转换为一个带有
apply
方法的伴生对象。2012年,添加了第二种
apply
方法,并弃用了第一种方法


Scala中的函数支持varargs,并且工作良好。Scala中的Case类也支持varargs。在本例中,这是使用varargs的
apply
方法,其中有两种。编译器支持使用多个
apply
方法,但这种方法与varargs的交互方式可能会导致模式匹配困难。当scala xml维护人员添加第二个apply方法来添加新参数时,我认为他们不了解他们的更改对模式匹配的影响。

后一种解决方案几乎就是我所使用的,感谢这一增强。当我正确阅读您的答案时,这是Scala中的错误/缺陷吗?我以前在重载函数中看到过这一点,其中有一个
*
-参数?@Jan问得好。我在上面的答案中添加了另一段来回答这个问题。当
e@Elem…
节点的类型实际上是
node
时,我们用
e@Elem…
的好解决方案不起作用。所以我坚持使用我的
node.asInstanceOf[Elem]。minimizeEmpty
变量:)@Jan这很奇怪。我想我不知道怎么会这样。
元素不是
节点的子类吗。在
Elem
案例中,您将如何获得
节点
?我如何知道?我和你看起来一样惊讶。但编译器明确指出,e是Node类型的。
case Elem(p,l,a,s,m:Boolean,child @ _*)
case Elem(p,l,a,s,m @(_:Boolean),child @ _*) 
case Elem(p,l,a,s,m @Boolean,child @ _*)
> set scalacOptions += "-deprecation"
> console
scala> import scala.xml._

scala> val node:Elem = <item><category>1</category></item>

scala> node match {
         case Elem(p,l,a,s, child @ _*) ⇒ Elem(p,l,a,s,child.filter(_.label != "category") ++ <category>2</category>:_* )
       }
<console>:17: warning: method apply in object Elem is deprecated: Use the other apply method in this object
  case Elem(p,l,a,s, child @ _*) ⇒ Elem(p,l,a,s,child.filter(_.label != "category") ++ <category>2</category>:_* )
                                   ^
scala> node match {
     |   case e @ Elem(p,l,a,s, child @ _*) ⇒ Elem(p,l,a,s,e.minimizeEmpty,child.filter(_.label != "category") ++ <category>2</category>:_* )
     | }
res1: scala.xml.Elem = <item><category>2</category></item>