2

我遇到了这种让我吃惊的行为。本质上,如果我从两个不同的 XML 文字创建“相同”的 XML Elem,它们就不能相互相等。这里的独特之处在于我在一个中使用a Boolean,在另一个中使用a 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 正在存储底层类型,而 Boolean 并不严格等于 String。

这是正确的解释吗,谁能解释这里到底发生了什么?我找不到检查两个节点内的底层类型的方法。如果我看孩子们,他们只是看起来很Nodes。

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

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

1 回答 1

3

你的解释是正确的。fromStringis的孩子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

的孩子fromBooleanscala.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

所以dataoffromString的孩子Atom有类型String,而dataoffromBoolean的孩子有Atom类型BooleanAtom( )的相等实现scala.xml.Atom#strict_==只是data直接比较 ,所以 theStringBoolean比较不相等。

我不确定区分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

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

于 2018-04-26T00:02:49.893 回答