为了更新xml节点上的子节点,您可以执行此操作(此处缺少其他SO-ticket ref):
val node:Node = <item><category>1</category></item>
val root = node match {
case Elem(p,l,a,s, child @ _*) ⇒ Elem(p,l,a,s,child.filter(_.label != "category") ++ <category>2</category>:_* )
case _ ⇒ node // error case
}
这给出了一个弃用的警告,因为应该使用Elem方法将minimizeEmpty
的显式命名作为第五个参数:
val node:Node = <item><category>1</category></item>
val root = node match {
case Elem(p,l,a,s,m,child @ _*) ⇒ Elem(p,l,a,s,m,child.filter(_.label != "category") ++ <category>2</category>:_* )
case _ ⇒ node // error case
}
然而,这不起作用,因为它总是在没有显式布尔参数的情况下应用apply方法的解构,因此m
总是得到类型Node
并且没有任何适合。
那么如何帮助编译器选择正确的Constructor / apply-method呢? (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
答案 0 :(得分:1)
如果查看弃用警告,请使用随播对象的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>:_* )
^
将变量绑定参数与@
:
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>
我有点惊讶Elem
的模式匹配有这个缺陷。出于某种原因,Elem
在2007年从案例类转换为具有apply
方法的伴随对象。 2012年,添加了第二个apply
方法并弃用了第一个方法。
Scala中的函数支持varargs,它们运行良好。 Scala中的案例类也支持varargs。在这种情况下,这是使用varargs的apply
方法,其中有两个。编译器支持使用多个apply
方法,但是与varargs交互的方式可能会使模式匹配变得困难。我不认为scala-xml维护者在添加第二个应用方法添加新参数时,了解模式匹配方面的更改影响。