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,它们似乎只是 Node
s.
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 Atom
的 data
具有类型 String
,而 fromBoolean
的 data
] 的 Atom
具有类型 Boolean
。 Atom
(scala.xml.Atom#strict_==
) 的相等实现只是直接比较 data
,因此 String
和 Boolean
比较不相等。
我不确定区分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><</b>
res7: Boolean = false
scala> <b>></b> == <b>></b>
res8: Boolean = false
因此尝试手动实施比较可能是值得的。
我 运行 喜欢这种让我感到惊讶的行为。本质上,如果我从两个不同的 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,它们似乎只是 Node
s.
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 Atom
的 data
具有类型 String
,而 fromBoolean
的 data
] 的 Atom
具有类型 Boolean
。 Atom
(scala.xml.Atom#strict_==
) 的相等实现只是直接比较 data
,因此 String
和 Boolean
比较不相等。
我不确定区分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><</b>
res7: Boolean = false
scala> <b>></b> == <b>></b>
res8: Boolean = false
因此尝试手动实施比较可能是值得的。