我错过了一些我收集的相当简单的语法。我正在尝试将元素标签重写为其他内容,并保持其他所有内容不变。
object htmlRule extends RewriteRule {
override def transform(n: Node): Seq[Node] = n match {
case Elem(prefix, "document", attribs, scope, child@_*) =>
Elem(prefix, "html", attribs, scope, child)
case other => other
}
}
现在,我要求解释两件事:
1)“child @ _ *”究竟用简单的英语表示什么?
2)如何捕获“child @ _ *”的值并让它直接传递给新元素?目前,我得到以下错误,这是有道理的。
[error] found : Seq[scala.xml.Node]
[error] required: scala.xml.Node
[error] Elem(prefix, "html", attribs, scope, child)
我也不喜欢这个,所以如果有一个更好的方法来简单地更改特定节点的元素名称,那就让它吧......
谢谢, --tim
答案 0 :(得分:5)
符号:
case ... bindVar @ patternConstraint ... => /* bindVar is bound to what patternConstraint matched here */
允许您在捕获受约束的整体值(作为bindVar)时匹配值(patternConstraint部分)内的“内部”。
在您的特定情况下,child @ _*
,_
表示“不关心”,*
表示一系列值,child @
表示将子项绑定到整个序列。
频繁使用此功能是嵌套模式(通常提到案例类):
case expr @ Expr(op, lhs, rhs) => // Do stuff with expr, op, lhs and rhs
在这里,测试匹配的目标以查看它是否是Expr
的实例,如果是,op
绑定到Expr
的运算符,{{ 1}}和lhs
分别绑定在左侧和右侧。并且rhs
绑定到Expr实例本身。
答案 1 :(得分:1)
Elem
不是案例类,它是带有伴随对象的“普通”类。有一种方法可以编写普通(非案例)类来模拟案例类。但更典型的是,一个视图案例类作为编写一堆样板代码的简写,其中一些在类中,一些在隐式创建的伴随中。在这种情况下,相关位是伴随对象中的unapply
和/或unapplySeq
方法。这些方法使非案例类适合模式匹配。
对于Elem
,相关的匹配“签名”是object scala.xml.Elem#unapplySeq(...)
的签名,具体为:
def unapplySeq(n: Node): Option[(String, String, MetaData, NamespaceBinding, Seq[Node])]
在那里,您可以看到与Elem
匹配时创建的绑定模式。它们确实对应于您在示例代码中使用的模式。