2012-11-01 1 views
8

Pouvons-nous obtenir le type de val s: String en utilisant la réflexion de l'extérieur de la fonction f?Réflexion de sous-typage structurel

val f = (r: {val s: String}) => { 
} 
+0

Sous 2.9 ou 2.10 ou cela n'a-t-il pas d'importance? –

+0

Peu importe 2.9 ou 2.10. Mais j'utilise habituellement 2.9.2. – sndyuk

+1

Je doute fortement que ce soit possible en 2.9 sans travailler avec le compilateur. En 2.10 il y a la réflexion api qui permettra probablement d'inspecter le type de 'r'. – pedrofurla

Répondre

10
scala> import scala.reflect.runtime.{universe => ru} 
import scala.reflect.runtime.{universe=>ru} 

scala> import scala.reflect.runtime.universe._ 
import scala.reflect.runtime.universe._ 

scala> def typeOf[T: ru.TypeTag](x: T) = ru.typeOf[T] // capture compile-time type info 
typeOf: [T](x: T)(implicit evidence$1: reflect.runtime.universe.TypeTag[T])reflect.runtime.universe.Type 

scala> val f = (r: {val s: String}) => {} 
f: AnyRef{val s: String} => Unit = <function1> 

scala> val tpe = typeOf(f) 
tpe: reflect.runtime.universe.Type = scala.AnyRef{val s: String} => Unit 

scala> ru.showRaw(tpe) 
res0: String = TypeRef(ThisType(scala), scala.Function1, List(RefinedType(List(TypeRef(ThisType(scala), newTypeName("AnyRef"), List())), Scope(newTermName("s"))), TypeRef(ThisType(scala), scala.Unit, List()))) 

scala> val ru.TypeRef(_, _, refinement :: _) = tpe 
refinement: reflect.runtime.universe.Type = scala.AnyRef{val s: String} 

avec la réflexion Scala, on peut également générer des objets fantaisie pour les types de structure comme suit: https://gist.github.com/4008389. L'essentiel lié fait ceci en utilisant des boîtes à outils et la réflexion d'exécution, mais ce scénario peut également être implémenté avec des macros.

+0

Quelle version de Scala utilisez-vous? Je reçois un avertissement sur la dernière déclaration: 'warning: le type abstrait reflect.runtime.universe.TypeRef est décoché car il est éliminé par effacement'' – sschaef

+1

L'importation est nécessaire. Il introduit une balise de classe pour TypeRef dans la portée, ce qui élimine l'avertissement non contrôlé. –

+0

Est-il possible de créer une instance de raffinement? – sndyuk