Scala XML 文字 - 布尔值与字符串

Scala XML literal - Boolean vs String

我 运行 喜欢这种让我感到惊讶的行为。本质上,如果我从两个不同的 XML 文字创建 "the same" XML Elem,它们将不相等。这里的独特之处在于我在一个中使用 Boolean,在另一个中使用 String

scala> import scala.xml._
import scala.xml._

scala> val t: Boolean = true
t: Boolean = true

scala> val fromBoolean: Elem = <b>{t}</b>
fromBoolean: scala.xml.Elem = <b>true</b>

scala> val fromString = <b>true</b>
fromString: scala.xml.Elem = <b>true</b>

scala> fromString == fromBoolean
res0: Boolean = false

这是预期的行为吗?

似乎 Scala 正在存储底层类型,布尔值并不严格等于字符串。

这是正确的解释吗,谁能解释一下这里到底发生了什么?我找不到检查两个节点内的基础类型的方法。如果我查看 children,它们似乎只是 Nodes.

scala> fromString.child(0)
res1: scala.xml.Node = true

scala> fromBoolean.child(0)
res2: scala.xml.Node = true

您的解释是正确的。 fromString 的 child 是 scala.xml.Text,扩展了 scala.xml.Atom[String]:

scala> fromString.child(0).getClass.getName
res1: String = scala.xml.Text

scala> fromString.child(0).asInstanceOf[xml.Atom[_]].data.getClass.getName
res2: String = java.lang.String

fromBoolean的child是scala.xml.Atom[Boolean]:

scala> fromBoolean.child(0).getClass.getName
res3: String = scala.xml.Atom

scala> fromBoolean.child(0).asInstanceOf[xml.Atom[_]].data.getClass.getName
res4: String = java.lang.Boolean

因此 fromString 的 child Atomdata 具有类型 String,而 fromBooleandata ] 的 Atom 具有类型 BooleanAtom (scala.xml.Atom#strict_==) 的相等实现只是直接比较 data,因此 StringBoolean 比较不相等。

我不确定区分Atom数据类型的目的是什么。在我看来 Atom 无论如何都应该比较其数据的 toString 值。所以这种行为可能是一个错误。

作为解决方法,我建议将原子值显式转换为 String。在这种情况下,平等有效:

scala> <b>{true.toString}</b> == <b>true</b>
res5: Boolean = true

Scala xml 比较确实有更多的怪癖:

scala> <foo:b xmlns:foo="foo"/> == <foo:b xmlns:foo="bar"/> 
res6: Boolean = true

scala> <b>{"<"}</b> == <b>&lt;</b>
res7: Boolean = false

scala> <b>></b> == <b>&gt;</b>
res8: Boolean = false

因此尝试手动实施比较可能是值得的。