2013-01-23 24 views
1

明顯的比較之後,我有一些問題,即A <: Array[_]鑄造兩個數組中階

我創建了一個功能比較manifest和投數據到陣列向好型投我objeсtVariable[A]

我的目標Variable[A]商店Manifest[A]到DEF '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 
     } 
} 
} 

有可能是我的一部分的一個錯誤,當我instanciate用於比較的變量對象,所以我給了instanciation的代碼:

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.value含有Array[Double]

當我println()的兩個清單:

  • 變量數組類型:Array[double]
  • m型:Array[Double]

它似乎是一個Array[Double]不是Array[double],我該如何解決/施放此?

+0

K記住Scala的'Array'是一個JVM'Array',它們是_invariant_。因此,沒有兩個不同的'Array'類型彼此以子類型關係站立。 –

+0

我認爲最好的建議是避免初學者使用Array。其次,至少要公開地避免施法。 Scala模式匹配是處理動態類型決策的更好方法。 –

+0

我嘗試在我的代碼中使用這種方法在現實中:http://stackoverflow.com/questions/3213510/what-is-a-manifest-in-scala-and-when-do-you-need-it;但它在鏈接工作可能是因爲它使用List而不是Array ... – reyman64

回答

0

最後,在同事方法的幫助下,unArrayify Array,我解決了我的運行時類型實現問題。現在我可以比較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

1

這開始了作爲一個評論,因爲它不是一個答案,但它太大了,需要格式化(加上我的瀏覽器選項卡的自動重載導致它失去在第一時間......)

所以。對於初學者,您的代碼片段不完整和/或不正確。潛在地,有些進口可能會改變該代碼的含義。其次,如圖所示,它不會編譯,因爲看起來是一個正式的類型參數,A沒有約束力。因此除非你有一個名爲A的實際類型不能編譯。

其次,Double可能不明確。有scala.Doublejava.lang.Double,它們是不同的。 Scala自動包裝盒和-unboxes原始類型,通常當它們用於實例化泛型方法的類型參數(並且不使用專業化)時。這樣的結果是Array[scala.Double]不同於Array[java.lang.Double]。 Scala會在可能的情況下創建基本類型的數組,但Array[java.lang.Double]顯式是一個盒裝雙精度浮點數組。

E.g.:

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; 

那麼請您填好示例代碼的遺漏細節?

+0

感謝您的回答,我更新我的代碼,我希望現在這是一個更好的問題 – reyman64

+0

在同事的幫助下,我找到了我的問題的答案,我希望答案可以幫助其他人:)另外,非常感謝您的啓發。 – reyman64