我注意到scala.xml.Atom
采用类型参数A
,即使它的所有子类都扩展Atom[String]
,文档说“Atom类为文本提供XML节点(PCDATA) )“。
是否存在使用字符串以外的类型参数实例化Atom的合法用例?
更具体地说,我有兴趣使用Scala XML文字来定义一个很好的DSL,用于定义内存中基于树的文档结构,其中许多节点都是现有的scala类。使用<document>{new JButton("Hi")}</document>
并访问Atom[JButton]
中的非文本数据非常好,而无需为每个现有类定义XML序列化方案。
这是一个合法的用例,还是我滥用Scala XML库的当前实现?
答案 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支持可能会在将来被清理,而这个相当模糊的功能可能无法生存。