【发布时间】:2012-03-16 04:03:55
【问题描述】:
我是 Scala 类型系统的新手,我正在尝试通过这个 JAXB Marshalling 示例来探索它。如果将参数的类型从 toString 更改为 AnyRef,它就可以工作。但是,我想通过类型系统表示 toString 的参数必须与具体构造函数的类型参数的类型相同。有没有办法做到这一点?
我不明白为什么下面的错误消息似乎表明 typ = XMLMarshaller[TestObj] 而不仅仅是 TestObj。在我的调试器中,typ=TestObj。非常感谢您对这个特定问题的任何帮助或对这段代码的一般见解!
error: type mismatch; found : TestObj required: _1.typ where val
_1: XMLMarshaller[TestObj]
val o = new XMLMarshaller[TestObj]().toString(new TestObj("hello","world"))
这是代码,只需粘贴到 REPL 中:
import javax.xml.bind.{Marshaller, JAXBContext}
import java.io.{ByteArrayInputStream, StringWriter}
import org.jboss.resteasy.plugins.providers.jaxb.json.JettisonMappedContext
import javax.xml.bind.annotation.{XmlRootElement, XmlAccessorType, XmlAccessType}
abstract class XMarshaller {
val context:JAXBContext
type typ <: AnyRef
def toString(obj:typ): String = {
val marshaller:Marshaller = context.createMarshaller()
val sw = new StringWriter
marshaller.marshal(obj, sw)
sw.toString
}
def valueOf(xmlString:String): typ = {
val marshaller = context.createUnmarshaller()
marshaller.unmarshal(new ByteArrayInputStream(xmlString.getBytes())).asInstanceOf[typ]
}
}
class XMLMarshaller[T](implicit mT:Manifest[T]) extends XMarshaller {
val typ = mT.erasure
val context = JAXBContext.newInstance(typ)
}
class JSONMarshaller[T](implicit mT:Manifest[T]) extends XMarshaller {
val typ = mT.erasure
val context = new JettisonMappedContext(typ)
}
@XmlRootElement
@XmlAccessorType(value = XmlAccessType.FIELD)
case class TestObj(x:String, y:String){
def this() {this("","")}
}
object Test {
def main(args: Array[String]) {
val o = new XMLMarshaller[TestObj]().toString(new TestObj("hello","world"))
println(o)
}
}
【问题讨论】: