为什么scala.xml.Atom类型参数化?

时间:2011-02-28 17:32:36

标签: scala

我注意到scala.xml.Atom采用类型参数A,即使它的所有子类都扩展Atom[String],文档说“Atom类为文本提供XML节点(PCDATA) )“。

是否存在使用字符串以外的类型参数实例化Atom的合法用例?

更具体地说,我有兴趣使用Scala XML文字来定义一个很好的DSL,用于定义内存中基于树的文档结构,其中许多节点都是现有的scala类。使用<document>{new JButton("Hi")}</document>并访问Atom[JButton]中的非文本数据非常好,而无需为每个现有类定义XML序列化方案。

这是一个合法的用例,还是我滥用Scala XML库的当前实现?

2 个答案:

答案 0 :(得分:3)

如果您查看sources,原因会被揭开。 Atom是通用的,因为它将传递的对象转换为String。所以你可以传递一个JButton但它会调用它的toString方法。 (第48行是重要的)

我想可以将数据从原子中取出来:

val doc = <document>{ 42 }</document>

doc.child.head match { 
  case i: Atom[Int] => i.data / 7 
  case _ => error("Unsupported type")
}

返回6。所以你的计划会奏效。我仍然认为基于抽象类和案例类的树是更好的选择,因为使用您的方法,所有类型的安全性都会消失,因为您可以传递所有内容,因此在运行时之前不会发现类型错误。

答案 1 :(得分:3)

如果查看http://sites.google.com/site/burakemir/scalaxbook.docbk.html?attredirects=0,您会发现Atom确实是“用于包含任何类型数据的节点,例如int,Date”。

正如您所观察到的,如果元素内部的嵌入式表达式不是字符串,则会将其转换为原子,例如

<foo>{42}</foo>

作为孩子使用Atom [Int]。

要将atom添加到属性值中,您必须编写

<foo life={new Atom(42)}>

(在“书”中,它只是Atom(42),但那时 - 由于案例类继承已被弃用,因此Atom不再是案例类。)

所以,是的,你想要做的完全符合设计精神。

但是这个设计已经有好几年了,很多人都对一些决定不满意。 Scala中的XML支持可能会在将来被清理,而这个相当模糊的功能可能无法生存。