2013-02-15 2 views
5

При объявлении последовательности узла в Scala в качестве литералов вы получением scala.xml.NodeBuffer, который является изменяемым (она простирается ArrayBuffer[scala.xml.Node], который, в свою очередь увеличивает Seq[scala.xml.Node]):Почему XML-литералы дают изменяемые объекты в Scala?

scala> val xml = <a /><b /> 
xml: scala.xml.NodeBuffer = ArrayBuffer(<a></a>, <b></b>) 

scala> xml += <c /> 
res46: xml.type = ArrayBuffer(<a></a>, <b></b>, <c></c>) 

scala> xml 
res47: scala.xml.NodeBuffer = ArrayBuffer(<a></a>, <b></b>, <c></c>) 

Это противоречит философии в Scala использовать неизменные объекты и функционального программирования. Почему коллекции по умолчанию неизменяемы, но XML-литералы (которые являются гражданами первого класса) в данном случае не являются?

Однако возможно ли безопасное определение последовательности неизменяемых узлов с использованием XML-литералов?

ответ

4

Кажется, что неизменяемым литералам XML требуется один корневой узел (как и XML). scala.xml.Group позволяет сделать это, используя корневой узел «пустышка» <xml:group />.

Это красноречиво описано в документах API как «Взлом для группировки узлов XML в одном узле для вывода».

scala> val xml = <xml:group><a /><b /></xml:group> 
xml: scala.xml.Group = <a></a><b></b> 

Когда вы сочетаете этот фрагмент с другими XML, узел группы исчезает:

scala> <foo>{xml}</foo> 
res1: scala.xml.Elem = <foo><a></a><b></b></foo> 
Смежные вопросы