2017-04-24 1 views
1

J'ai une fonction qui convertit un Something[Any] à un Something[X] à Scala en utilisant sans type:Comment revenir résultat de fonte et asInstanceOf à Scala en utilisant informes

import shapeless._ 
import shapeless.syntax.typeable._ 

def doCast[T: Typeable](v: Vector[Any]): T = v.cast[T].get 

Maintenant, je veux accéder à la liste par index:

val a = Vector[Any](1,2,3); 
println(doCast[Vector[Int]](a)(1)) 

Mais cela jette une exception:

/path/to/Test.scala:12: error: type mismatch; 
found : Int(1) 
required: shapeless.Typeable[Vector[Any]] 
     println(doCast[Vector[Int]](a)(1)) 
            ^
one error found 

Cependant, si j'attribue ce résultat à une variable d'abord, il imprime correctement 2:

val a = Vector[Any](1,2,3); 
val c = doCast[Vector[Int]](a) 
println(c(1)) 

De même, si je jetai le résultat en utilisant asInstanceOf, il fonctionne correctement:

val a = Vector[Any](1,2,3); 
println(doCast[Vector[Int]](a).asInstanceOf[Vector[Int]](1)); 

peut Je crée une fonction qui renvoie le résultat indexable?

J'ai essayé de le faire, mais mes tentatives ne fonctionne pas:

def doCast2[T](v: Vector[Any]): T = doCast(v).asInstanceOf[T] 

donne cette erreur:

/path/to/Test.scala:10: error: diverging implicit expansion for type shapeless.Typeable[T] 
starting with method inrTypeable in object Typeable 
    def doCast2[T](v: Vector[Any]): T = doCast(v).asInstanceOf[T] 
             ^
one error found 

et

def doCast2[T](v: Vector[Any]): T = doCast[T](v).asInstanceOf[T] 

donne cette erreur:

/path/to/Test.scala:10: error: 
class type required but T found 
    def doCast2[T](v: Vector[Any]): T = doCast[T](v).asInstanceOf[T] 
              ^
one error found 

Répondre

1

Le problème semble être que la signature effective de doCast après désucrage est converti de:

def doCast[T: Typeable](v: Vector[Any]): T 

à

def doCast[T](v: Vector[Any])(implicit ev1: Typeable[T]): T 

Donc lorsque vous appelez comme ça

doCast[Vector[Int]](a)(1) 

vous passent 1 dans la position d'un typable [T].

La solution la plus simple est de spécifier le paramètre directement:

doCast[Vector[Int]](a)(implicitly)(1) 

Ou utilisez le val séparé pour le vecteur après doCast