Scala XML字面量:布尔值与字符串创建的Elem不相等问题
为什么Scala中布尔值和字符串字面量创建的XML Elem不相等?
哈哈,这个坑我之前也踩过!Scala的XML字面量处理确实有这么个容易让人困惑的细节,我来给你掰扯清楚原因,以及怎么解决。
先把你的完整场景代码贴出来,方便大家对照:
import scala.xml._ val t: Boolean = true val fromBoolean: Elem = <b>{t}</b> val fromString = <b>true</b> // 运行这行你会发现结果是false,是不是超意外? println(fromBoolean == fromString)
问题的核心原因
Scala在处理XML字面量里的嵌入表达式时,会根据表达式的类型做不同的转换:
- 当你直接写
<b>true</b>时,Scala的XML解析器会把内部的"true"解析成一个**scala.xml.Text节点**,这个节点存的是字符串类型的"true"。 - 当你嵌入布尔值
t时,因为Boolean不是Node或NodeSeq的子类,Scala会自动把它包装成一个**scala.xml.Atom[Boolean]节点**,这个节点内部存的是原始的布尔值true,而不是字符串。
虽然这两个节点打印出来都是"true",但它们的类型和内部存储的东西完全不一样:
Text("true")的equals方法比的是字符串内容Atom[Boolean](true)的equals方法比的是内部的布尔值对象
而Scala比较Elem的时候会递归检查所有子节点,所以这俩看起来一模一样的Elem,就因为子节点的差异返回false了。
解决办法
要让两个Elem相等,只要把嵌入的布尔值显式转成字符串,确保生成的是Text节点就行:
方法1:直接调用toString
val fromBooleanFixed: Elem = <b>{t.toString}</b> println(fromBooleanFixed == fromString) // 现在会输出true啦
方法2:显式创建Text节点(更严谨一点)
val fromBooleanFixed: Elem = <b>{Text(t.toString)}</b> println(fromBooleanFixed == fromString) // 同样输出true
这样处理后,两个Elem的子节点都是Text("true"),比较的时候就会返回你预期的结果了。
内容的提问来源于stack exchange,提问作者dwikle
相关产品推荐
相关产品推荐

