2

DSL といくつかのランタイム コードがあります。問題は、実行時にどこかに到達したことです:

val clazz: Class[_ <: java.io.Serializable] = classOf[java.lang.String]
val value: java.io.Serializable = "abc"

そして私はクラスを持っています

class MyWrapper[T <: java.io.Serializable](val data: T)(implicit m: Manifest[T]) {
  override def toString = m.runtimeClass
}
val wrapper = new MyWrapper(value)

java.lang.String問題は、の呼び出しから戻る必要があることですtoString。しかし、私は得java.io.Serializableました。残念ながら、java.io.Serializableサブタイプごとに固定パターン マッチングを作成することも (これはおかしいでしょう)、MyWrapper明示的な withを作成することもできませんnew MyWrapper[String](value)。のタイプがわかりません。valueおそらく のサブタイプですSerializable

値の型が変数と等しいことがわかっている場合、実行時に型/マニフェスト値を渡す方法はありますclazzか?


更新 (Régis Jean-Gilles の解決策は機能しません)。REPL テスト:

val clazz: Class[_ <: java.io.Serializable] = classOf[java.lang.String]
val value: java.io.Serializable = "abc"

class MyWrapper[T <: java.io.Serializable](val data: T)(implicit m: Manifest[T]) {
  override def toString = m.runtimeClass.getName
}
val wrapper = new MyWrapper(value)
//val wrapper = new MyWrapper(value)(ClassManifest.fromClass(clazz).asInstanceOf[ClassTypeManifest[java.io.Serializable]])
//val wrapper = new MyWrapper(value)(ClassManifest.fromClass(clazz))
System.err.println(wrapper.toString)

マニフェストを明示的に渡そうとすると、エラーが発生しました。

scala> :load test.scala
Loading test.scala...
clazz: Class[_ <: java.io.Serializable] = class java.lang.String
value: java.io.Serializable = abc
defined class MyWrapper
<console>:10: error: type mismatch;
 found   : scala.reflect.ClassManifest[_$1] where type _$1 <: java.io.Serializable
    (which expands to)  scala.reflect.ClassTag[_$1]
 required: Manifest[java.io.Serializable]
       val wrapper = new MyWrapper(value)(ClassManifest.fromClass(clazz))
                                                                 ^
<console>:8: error: not found: value wrapper
              System.err.println(wrapper.toString)

また、マニフェストを明示的にキャストできません。

アプリケーションをコンパイルしようとすると、さらに奇妙なエラーが発生します -

[error]  found   : scala.reflect.ClassManifest[(some other)_0(in method setProperty)]
[error]     (which expands to)  scala.reflect.ClassTag[(some other)_0(in method setProperty)]
[error]  required: Manifest[_0(in method setProperty)]
[error]           new Value.Static(default, Context.virtual(element))(ClassManifest.fromClass(elementProperty.typeClass)))

IMHO Régis Jean-Gilles はソリューションに非常に近いです。Scala 2.10 で動作させるには?

4

2 に答える 2

2

私の理解が正しければ、型の消去を回避するためにマニフェストを使用していますが、特定の時点ではClass[_]しかないので、マニフェストに戻す必要があります。正しい?

その場合は、 を使用ClassManifest.fromClassして、暗黙的な値として明示的に渡すことができますm

val wrapper = new MyWrapper(value)(Manifest.classType(clazz))

おそらくそれを抽象化する必要があります:

object MyWrapper {
  def fromRuntimeType[T <: java.io.Serializable]( value: T ): MyWrapper[T] = {
    new MyWrapper(value)(Manifest.classType(value.getClass))
  }
}

ただし、そもそもインスタンスしかないため、 Class再び型消去に翻弄されることに注意してください。これは、(マニフェストを取得する必要がある) クラスがジェネリックである場合、 によって返されるマニフェストに型パラメーター情報がないことを意味しますClassManifest.fromClass

于 2013-01-29T12:54:28.523 に答える
0

しません

override def toString = data.getClass.getName

すでに働いていますか?それが得られjava.lang.Stringます。

于 2013-01-29T12:58:06.473 に答える