1

Variable[A]オブジェクトをどこにキャストするのに問題がありますA <: Array[_]

データを比較manifestして、適切な型の配列にキャストする関数を作成します。

私のオブジェクトはaをdefにVariable[A]保存しますManifest[A]'type'

私は既存のソフトウェアのプラグインを作成しているので、これVariableを良いタイプでインスタンス化するのは私ではありません。

プロトタイプオブジェクトとクラス:

object Prototype {
  def apply[T](n: String)(implicit t: Manifest[T]) = new Prototype[T] {
    val name = n
    val `type` = t
  }
}

trait Prototype[T] {
  def name: String
  def `type`: Manifest[T]
}

変数オブジェクトとクラス:

object Variable {
  def apply[T](p: Prototype[T], v: T) = new Variable[T] {
    val prototype = p
    val value = v
  }
}

trait Variable[T] {
  def prototype: Prototype[T]
  def value: T
}

使用する私のクラス:

class XYDataReader[A <: Array[_]](var data: Iterable[Variable[A]]) {

    def get[T](variable: Variable[A])(implicit m: Manifest[T]): Option[T] = {
        if (variable.prototype.`type` <:< m) {
          Some(variable.value.asInstanceOf[T])
        } else {
          None
        } 
}
}

比較に使用されるVariableオブジェクトをインスタンス化するときに、おそらく私の部分の間違いがあるので、インスタンス化のコードも提供します。

val v:List[Any] = List[Any](1.2,2,3)
val p = Prototype[Array[Any]]("col1")
val myVariable = Variable(p, v.toArray(ClassTag(p.`type`.runtimeClass)))

を含むget[Array[Double]](myVariable)場所を呼び出すと、パターンマッチングが失敗した理由がわかりませんmyVariable.valueArray[Double]

println()が2つのマニフェストのとき:

  • 可変配列型:Array[double]
  • mタイプ:Array[Double]

Array[Double]ではないようですがArray[double]、どうすればこれを解決/キャストできますか?

4

2 に答える 2

1

これは回答ではないため、コメントとして開始されましたが、大きすぎて書式設定が必要です(さらに、ブラウザタブの自動再読み込みにより、最初に失われました...)

だから...まず、コードのスニペットが不完全であるか、正しくありません。そのコードの意味を変更する可能性のあるインポートが有効になっている可能性があります。第二に、示されているように、正式な型パラメーターのように見えるものはコンパイルされず、Aバインディングはありません。Aしたがって、コンパイルされない名前の実際の型がない限り。

第二に、Double潜在的にあいまいです。と の両方がscala.Doubleありjava.lang.Double、それらは区別されます。Scala はプリミティブ型を自動的にボックス化およびボックス化解除します。これは通常、ジェネリック メソッドの型パラメーターをインスタンス化するために使用される場合です (特殊化は使用されません)。この結果、 は とArray[scala.Double]は異なりArray[java.lang.Double]ます。Scala は可能であればプリミティブ型の配列を作成しますが、Array[java.lang.Double]明示的にボックス化された倍精度浮動小数点の配列です。

例えば:

scala> val d1: scala.Double = 123.456
d1: Double = 123.456

scala> val d2: java.lang.Double = 234.567
d2: Double = 234.567

scala> d1.getClass
res25: Class[Double] = double

scala> d2.getClass
res26: Class[_ <: Double] = class java.lang.Double

scala> val ad1: Array[scala.Double] = Array(123.456, 234.567)
ad1: Array[Double] = Array(123.456, 234.567)

scala> val ad2: Array[java.lang.Double] = Array(234.567, 345.678)
ad2: Array[Double] = Array(234.567, 345.678)

scala> ad1.getClass
res27: Class[_ <: Array[Double]] = class [D

scala> ad2.getClass
res28: Class[_ <: Array[Double]] = class [Ljava.lang.Double;

よろしければ、サンプル コードの不足している詳細を記入してください。

于 2013-01-23T16:48:01.580 に答える
0

最後に、配列を再帰的に unArrayify する同僚のメソッドの助けを借りて、実行時の型の具体化の問題を解決します。Array[double]これで、 と の等価性を比較できますArray[Double]

  // Convert unknow A en Array[T], so you need to call get with Type :
  // example : get[Array[Double](myVariable)
  // return an Array[Double] only if it's possible for this Variable, else it return None
  def get[T](variable: Variable[A])(implicit m: Manifest[T]): Option[T] = {
    if (ClassUtils.assignable(variable.prototype.`type`.runtimeClass, m.runtimeClass)) {
      val casted = variable.prototype.`type`.runtimeClass.cast(variable.value)
      Some(casted.asInstanceOf[T])
    } else {
      None
    }

これらの方法が他の人に役立つことを願っています:)

ここで支援方法を見ることができClassUtils.assignableます:

https://gist.github.com/4686167

ソースフォージプロジェクトで:

https://forge.iscpif.fr/projects/openmole/repository/revisions/master/entry/core/openmole/misc/org.openmole.misc.tools/src/main/scala/org/openmole/misc/tools/ obj/ClassUtils.scala

于 2013-01-31T20:38:17.090 に答える