如何匹配scala.xml.Elem的未预先定义的apply方法
要更新xml节点上的子节点,可以执行以下操作(此处缺少其他SO票证参考): 但是,这不起作用,因为它总是在没有显式布尔参数的情况下应用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
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>