Je suis en train de convertir une carte Scala [String, Tous] à une classe de cas utilisant la réflexion Scala (Scala 2,11) comme suit: -Carte Scala à la conversion de cas de classe
val m = Map("name" -> "ABC", "age" -> 7, "gender" -> "male")
case class someCC(name: String, age: Int, gender: String)
import scala.reflect.ClassTag
def createCaseClass[T](someMap : Map[String, Any])(implicit someClassTag : ClassTag[T]) = {
val ctor = someClassTag.runtimeClass.getConstructors.head
val args = someClassTag.runtimeClass.getDeclaredFields.map(x => someMap(x.getName))
ctor.newInstance(args: _*).asInstanceOf[T]
}
cela se traduit malheureusement dans une compilation erreur -
Name: Unknown Error
Message: <console>:106: error: type mismatch;
found : Array[Any]
required: Array[_ <: Object]
Note: Any >: Object, but class Array is invariant in type T.
You may wish to investigate a wildcard type such as `_ >: Object`. (SLS 3.2.10)
ctor.newInstance(args: _*).asInstanceOf[T]
^
Je suis assez nouveau à l'utilisation ClassTags et je comprends que cette erreur est principalement parce que java.lang.Object est un sous-ensemble de tout et de Tout pourrait inclure des objets non-java.
Lorsque j'ai essayé de remplacer Any par AnyRef (qui correspond à java.lang.Object dans JRE), l'appel de fonction entraîne une erreur de type incompatibilité.
import scala.reflect.ClassTag
def createCaseClass[T](someMap : Map[String, AnyRef])(implicit someClassTag : ClassTag[T]) = {
val ctor = someClassTag.runtimeClass.getConstructors.head
val args = someClassTag.runtimeClass.getDeclaredFields.map(x => someMap(x.getName))
ctor.newInstance(args: _*).asInstanceOf[T]
}
val someCC = createCaseClass[someCC](m)
Name: Unknown Error
Message: <console>:106: error: type mismatch;
found : scala.collection.immutable.Map[String,Any]
required: Map[String,AnyRef]
val someCC = createCaseClass[someCC](m)
Quelle est la meilleure façon de résoudre cette erreur? Suggestions appréciées. Merci!
Mise à jour 1 - La mise à jour de cette commande pour implicitement passer un Any à AnyRef conduit à une erreur 'java.util.NoSuchElementException' lors d'un appel de fonction.
import scala.reflect.ClassTag
import scala.reflect.runtime.universe._
def createMyClass[T](someMap : Map[String, Any])(implicit someClassTag : ClassTag[T]) = {
val ctor = someClassTag.runtimeClass.getConstructors.head
val args = someClassTag.runtimeClass.getDeclaredFields.map(x => someMap(x.getName))
ctor.newInstance(args.asInstanceOf[Seq[AnyRef]]: _*).asInstanceOf[T]
}
val m = Map("name" -> "ABC", "age" -> 7, "gender" -> "male")
case class someCC(name: String, age: Int, gender: String)
createMyClass[someCC](m)
Name: java.util.NoSuchElementException
Message: key not found: $outer
StackTrace: at scala.collection.MapLike$class.default(MapLike.scala:228)
at scala.collection.AbstractMap.default(Map.scala:59)
at scala.collection.MapLike$class.apply(MapLike.scala:141)
at scala.collection.AbstractMap.apply(Map.scala:59)
at $$$e75186ae1b35495ffea8e318378149a$$$$anonfun$1.apply(<console>:135)
at $$$e75186ae1b35495ffea8e318378149a$$$$anonfun$1.apply(<console>:135)
at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:234)
at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:234)
at scala.collection.IndexedSeqOptimized$class.foreach(IndexedSeqOptimized.scala:33)
at scala.collection.mutable.ArrayOps$ofRef.foreach(ArrayOps.scala:186)
at scala.collection.TraversableLike$class.map(TraversableLike.scala:234)
at scala.collection.mutable.ArrayOps$ofRef.map(ArrayOps.scala:186)
at createMyClass(<console>:135)
Qu'est-ce que je fais mal ici?
Si vous le faites comme Java, vous devez passer dans l'instance de la classe externe dans le paramètre 'outer' $. – HTNW