Scala XML-литерал - логическое или строковое значение - PullRequest
0 голосов
/ 26 апреля 2018

Я столкнулся с таким поведением, которое меня удивило.По сути, если я создаю «один и тот же» XML Elem из двух разных литералов XML, они не могут сравниться друг с другом.Уникальным здесь является то, что я использую 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 хранит базовый тип, а логическое значение не является строго равным String.

Это правильная интерпретация, и кто-нибудь может объяснить, что именно здесь происходит?Я не смог найти способ проверить базовый тип в двух узлах.Если я смотрю на детей, то они кажутся Node с.

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

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

1 Ответ

0 голосов
/ 26 апреля 2018

Ваша интерпретация верна.Дочерний элемент fromString равен 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 равен 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

Так что data дочернего элемента fromString Atom имеет тип String, а data of fromBoolean s 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>&lt;</b>
res7: Boolean = false

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

Так что, возможно, стоит попробовать выполнить сравнение вручную.

...