Как написать двумерный массив в XML в Scala 2.8.0 - PullRequest
2 голосов
/ 22 апреля 2010

Следующий код (скопированный с вопрос около года назад ) отлично работает в Scala 2.7.7, но не работает правильно в Scala 2.8.0 (бета-версия 1, RC8).

import scala.xml

class Person(name : String, age : Int) {
    def toXml(): xml.Elem =
        <person><name>{ name }</name><age>{ age }</age></person>
}

def peopleToXml(people: Array[Person]): xml.Elem = {
    <people>{ for {person <- people} yield person.toXml }</people>
}

val data = Array(new Person("joe",40), new Person("mary", 35))

println(peopleToXml(data))

Выход (согласно 2.7.7) должен быть:

<people><person><name>joe</name><age>40</age></person><person><name>mary</name><age>35</age></person></people>

но вместо этого получается:

<people>\[Lscala.xml.Elem;@17821782</people>

Как мне заставить это вести себя так, как это было в 2.7.x?

Ответы [ 3 ]

4 голосов
/ 22 апреля 2010

Как говорит pst, результат - это то, что вы ожидаете от реального массива Java. Одно из изменений между 2.7 и 2.8 состоит в том, что Array[T] теперь точно настоящий массив Java. Новый дизайн коллекций означает, что выполнение операций коллекции Scala над массивом Java (например, map в вашем примере) вернет массив Java в качестве результата. Это означает, что следующее

for {person <- people} yield person.toXml

Раньше не возвращал массив Java, но теперь возвращает. Вы можете решить проблему, изменив тип аргумента people вашего метода peopleToXml следующим образом:

def peopleToXml(people: Seq[Person]): xml.Elem = {
    <people>{ for {person <- people} yield person.toXml }</people>
}

Это будет означать, что когда вы вызываете этот метод с аргументом Array, массив будет неявно преобразован в WrappedArray, который ведет себя так, как вы ожидаете. Это также даст вам возможность вызывать этот метод для коллекций без массивов.

3 голосов
/ 22 апреля 2010

Этот код требует двух преобразований. Сначала вы должны преобразовать Array[xml.Elem], который возвращается для понимания в Seq[xml.Elem], а затем неявное преобразование в xml.NodeSeq преобразует это в xml.NodeSeq.

Если вы измените peopleToXml на следующее, оно будет работать как положено:

def peopleToXml(people: Array[Person]): xml.Elem = {
  val a: Seq[xml.Elem] = for {person <- people} yield person.toXml
  <people>{a}</people>
}

Вы также можете сделать следующее, если хотите коротко: -)

def peopleToXml(people: Array[Person]): xml.Elem = {
  <people>{(for {person <- people} yield person.toXml): Seq[xml.Elem]}</people>
}
1 голос
/ 22 апреля 2010

Выход возвращает реальный массив Java, который строковый в соответствии с обычными правилами Java. Это передается выводом "[Ltype; @ref".

Возможно, вы можете преобразовать его (людей в или в результате) в список и получить лучшую семантику "для строк". Я представляю, что Scala 2.7.7 полностью возвращает другой (не массив) тип коллекции.

Борьба с гнилой битой с типами говорит о новой настройке Scala 2.8 Collections "в целом", но не учитывает специфику На scala-lang.org может быть больше добра и, как всегда, добро пожаловать в #scala на freenode: -)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...