scala.xml.NodeSeq上的模式匹配

时间:2016-12-02 20:43:20

标签: xml scala

假设:

$cat build.sbt
scalaVersion := "2.11.8"

libraryDependencies += "org.scala-lang.modules" %% "scala-xml"   % "1.0.6"

然后

$sbt console

def exactlyOne[A](xs: Seq[A]): Option[A] = xs match {
 case head :: Nil => Some(head)
 case _           => None
}

scala> val xml = <root><a/></root>
xml: scala.xml.Elem = <root><a/></root>

scala> xml \ "a"
res3: scala.xml.NodeSeq = NodeSeq(<a/>)

scala> exactlyOne( res3 )
res4: Option[scala.xml.Node] = None

显然,Seq#unapply未被使用:

scala> exactlyOne( Seq(1) )
res2: Option[Int] = Some(1)

我的理解是unapply将被调用,通常在班级的companion object上。

我找到Node#unapplySeqhttp://www.scala-lang.org/api/2.11.8/scala-xml/index.html#scala.xml.Node $ @ unapplySeq(n:scala.xml.Node):一些[(String,scala.xml.MetaData,Seq [scala.xml.Node])] ),但我不确定是否会被召唤。

这里有match调用哪种方法?

1 个答案:

答案 0 :(得分:2)

NodeSeq不是List,因此尝试将其匹配为一个将失败。如果您想使用某种类型的unapplySeq进行匹配,则需要以这种方式进行匹配:

def exactlyOne[A](xs: Seq[A]): Option[A] = xs match {
  case Seq(head) => Some(head)
  case _ => None
}

scala> exactlyOne(<root>hello</root>)
res5: Option[scala.xml.Node] = Some(<root>hello</root>)

scala> exactlyOne(<root>hello</root><foo>world</foo>)
res6: Option[scala.xml.Node] = None