2012-03-15 17 views
1

スカラ型システムが新しく、このJAXBマーシャリングの例で調べようとしています。パラメータの型をtoString to AnyRefに変更すると機能します。しかし、toStringのパラメータは、コンストラクタの型パラメータと同じ型でなければならないことを型システムを介して表現したいと思います。これを達成する方法はありますか?スカラ型システム - タイプエイリアスの不一致を理解するのに役立ちます

以下のエラーメッセージが、単にTestObjの代わりにtyp = XMLMarshaller [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に貼り付けると、コードです:クラスは、同じ名前の型のメンバと値 メンバーを持ち、いずれかを作成することはできません、ので、どのようにScalaの構文の作品の

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) 
    } 
} 

答えて

2

(あなたはいつでも を意味する文脈で伝えることができます)。

FooConcreteは、型のメンバ Typeをオーバーライドしない
abstract class FooAbstract { 
    type Type <: AnyRef 
} 

class FooConcrete[T<:AnyRef](implicit mt: Manifest[T]) extends FooAbstract { 
    val Type = mt.erasure 
} 

:あなたが持っている何

は類似しています。あなたが実際に好奇心が強い事はScalaはあなたがタイプをオーバーライドし、 完全に抽象的にそれを残すために失敗することを可能にするということである

class FooConcrete[T<:AnyRef](implicit mt: Manifest[T]) extends FooAbstract { 
    type Type = T 
} 

をしたいです。これが意図的なものかScala のバグか分かりません。

+0

オーウェン、助けてくれてありがとう。私のためにここではまだ少し謎が起こっている。最初に、valueOfは、あなたの説明の意味が、具体的なval typが抽象型typをオーバーライドしていなかったとしても、正しい型を返していました。それはどのように可能でしょうか? – scalapeno

+0

わかりません。あなたは正しいランタイムタイプを意味すると思いますか?ランタイム型は型変数の影響を受けないので、それほど驚くことではありません。私がよく分からないことは、なぜキャストの 'asInstanceOf [typ]'が成功したかということです。おそらく、それを 'AnyRef'にキャストした、つまり何もしなかったからです。 – Owen

関連する問題